我想知道我应该使用什么原则来编写一个以任何给定顺序获取其参数的bash脚本。 例如:
我在这里问的是:
我是否可以使用特定的方式(甚至是编程技术),以便可以按任何给定的顺序传递参数(除了文件名应始终遵循 -f 参数这一事实?
以下是一些调用示例:
以上两次执行应该产生相同的例子!
在回答时,请请记住,真正的问题有更多的参数和不同的结果!
答案 0 :(得分:0)
这是我为实现这个目的所写的脚本:
#!/bin/bash
# The code below was written to replace the -print and -delete options for
# -p and -d respectively, because getopts can't handle long args, I suggest
# you only use arguments of single letters to make your code more simple, but if
# you can't avoid it then this is a workaround
for ARGS in "$@"; do
shift
case "$ARGS" in
"-print") set -- "$@" "-p" ;;
"-delete") set -- "$@" "-d" ;;
*) set -- "$@" "$ARGS"
esac
done
# getopts works like this: you put all your arguments between single quotes
# if you put a ':' character after the argument letter (just like I did with
# the 'f' letter in the example below), it means this argument NEEDS an extra
# parameter. If you just use letters without the ':' it means it doesn't need
# anything but the argument itself (it's what I did for the '-p' and '-d' options)
while getopts 'f:pd' flag; do
case "${flag}" in
f) FILE=${OPTARG} ;;
p) COMMAND="print" ;;
d) COMMAND="delete" ;;
esac
done
echo "$COMMAND $FILE"
以下是运行的例子:
$ ./script.sh -f filename -print
print filename
$ ./script.sh -print -f filename
print filename
$ ./script.sh -f filename -delete
delete filename
$ ./script.sh -delete -f filename
delete filename
答案 1 :(得分:0)
以前的解决方案是一个很好的起点,我尝试使用它是因为它能够接受一个标志的多个参数,而且我认为这是一种更好的样式(也减少了未使用的变量):
#!/bin/bash
while [ $# -gt 0 ]; do
case "$1" in
--file|-f) filename=$2 ; shift;;
--print|-p) printCommand ;;
--delete|-d) deleteCommand ;;
*) break
esac
shift
done
此外,音符移位可以以移动数作为参数,这有助于保持其整洁。例如:
--two-files) filename1=$2; filename2=$3; shift 2;;