在 bash 中处理来自 file/cli/stdin 的参数
我可以看到自己最终编写了很多脚本,这些脚本根据命令行上的一些参数执行某些操作。
然后,这将发展到使用调度程序多次自动执行或多或少相同的事情。
为了防止自己必须为参数的每个变体创建一个新作业,我想创建一个简单的脚本框架,我可以使用它来快速创建采用相同参数的脚本:
- 命令行
- 来自指定路径的文件命令行
- 从 stdin 到 eof
我从 TAB delim 文件中获取参数或配置的最初方法如下:
if [ -f "$1" ]; then
echo "Using config file '$1'"
IFS=' '
cat $1 | grep -v "^#" | while read line; do
if [ "$line" != "" ]; then
echo $line
#call fn with line as args
fi
done
unset IFS
elif [ -d "$1" ]; then
echo "Using cli arguments..."
#call fn with $1 $2 $3 etc...
else
echo "Read from stdin, ^d will terminate"
IFS=' '
while read line; do
if [ "$(echo $line | grep -v "^#")" != "" ]; then
#call fn with line as args
fi
done
unset IFS
fi
因此,对于所有以前无疑做过此类事情的人:
- 您会/会如何去做呢?
- 我是不是太程序化了——用 awk 或类似的东西可以更好地完成这个任务吗?
- 无论如何,这是最好的方法吗?
I can see myself ending up writing a lot of scripts which do some thing based on some arguments on the command line.
This then progresses to doing more or less the same thing multiple times automated with a scheduler.
To prevent myself having to create a new job for each variation on the arguments, I would like to create a simple script skeleton which I can use to quickly create scripts which take the same arguments from:
- The command line
- A file from a path specified on the command line
- From stdin until eof
My initial approach for taking arguments or config from a TAB delim file was as follows:
if [ -f "$1" ]; then
echo "Using config file '$1'"
IFS=' '
cat $1 | grep -v "^#" | while read line; do
if [ "$line" != "" ]; then
echo $line
#call fn with line as args
fi
done
unset IFS
elif [ -d "$1" ]; then
echo "Using cli arguments..."
#call fn with $1 $2 $3 etc...
else
echo "Read from stdin, ^d will terminate"
IFS=' '
while read line; do
if [ "$(echo $line | grep -v "^#")" != "" ]; then
#call fn with line as args
fi
done
unset IFS
fi
So to all those who have doubtless done this kind of thing before:
- How did/would you go about it?
- Am I being too procedural - could this be better done with awk or similar?
- Is this the best approach anyway?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不确定我是否有点离谱,但听起来您正在尝试重新发明 xargs。
如果您有一个脚本,通常这样调用
您可以从标准输入获取参数,如下所示:
从文件
(假设 config_file 具有以下内容)
或从多个配置文件
Not sure whether I'm a bit wide of the mark, but it sounds like you are trying to reinvent xargs.
If you have a script, normally invoked as such
You can get the parameters from stdin as follows:
Our from a file
(assuming that config_file has the following content)
Or from multiple config files
您能想到一个具有您所描述的行为的标准 Unix 实用程序吗? (不,我不能。) 这表明你与你的目标略有偏离。
-f "$1"
和-d "$1"
的测试并不常规,但如果您的脚本仅适用于目录,也许这是有意义的。最终,我认为您需要一个如下接口:
显式但可选的
-f argumentlist
允许您指定要在命令行上读取的文件。否则,将处理命令行上指定的文件,除非没有此类参数,在这种情况下,将从标准输入读取要处理的文件名。这更接近于传统组织。我们可以稍后讨论如何处理名称中包含空格和换行符的文件名。您的代码核心将被编写为一次接受/处理一个文件名。这可以写成一个 shell 函数,这样可以最大限度地重用。
对此进行变体并不难。它也相当紧凑。
Can you think of a standard Unix utility that behaves as you describe? (No, I can't.) That suggests that you are slightly off-target with your goal.
The testing of
-f "$1"
and-d "$1"
is not conventional, but if your script only works on directories, maybe it makes sense.Ultimately, I think you need an interface like:
The explicit but optional
-f argumentlist
allows you to specify the file to read from on the command line. Otherwise, the files specified on the command line are processed, unless there are no such arguments, in which case the file names to be processed are read from standard input. This is a lot closer to a conventional organization. We can debate about the handling of file names with spaces and newlines in the names some other time.The core of your code will be written to accept/process one file name at a time. This might be written as a shell function, which allows the maximum reuse.
It is not very hard to ring the variations on this. It is also tolerably compact.