我知道这可能是一个愚蠢的问题,但这使我感到困惑。 我正在尝试编写一个接受标志和一个可选变量的shell脚本。一份文件。如果文件通过,它将从文件中读取。如果不是,则从stdin读取。我知道有人问过类似的问题,但我找不到特定问题的答案。
我在下面提供了一个说明问题的示例。为了简洁起见,我省略了一些部分(例如验证)。
我可以接受标志并从文件中读取。或者,我可以选择接受变量(文件)并从文件中读取。如果没有文件通过,那么我们从标准输入中读取。出于某种原因,当我尝试将两者结合时(接受标志,读取默认为stdin的可选文件),我得到一个错误。
这有效。
#!/bin/sh
set -eu
while IFS=, read -r f1
do
echo $f1
done <"${1:-/dev/stdin}"
我可以这样称呼... ./test.sh <<< "testing123"
或这个... echo "testing123" | ./test.sh
或这个... ./test.sh foo.csv
。
假设foo.csv包含testing123
,它们都将返回testing123
。
这也可以。
#!/bin/sh
set -eu
while true
do
case $1 in
-h|--help)
echo "-h"
exit
;;
--)
shift
break
;;
-?*)
echo "unknown"
;;
*)
break
esac
shift
done
while IFS=, read -r f1
do
echo $f1
done <"${1}"
我可以这样称呼./test.sh foo.csv
或./test.sh -f foo.csv
。第一种情况返回testing123
,第二种情况返回
unknown
testing123
由于某种原因,这不起作用。我不明白我在这里想念什么?
#!/bin/sh
set -eu
while true
do
case $1 in
-h|--help)
echo "-h"
exit
;;
--)
shift
break
;;
-?*)
echo "unknown"
;;
*)
break
esac
shift
done
while IFS=, read -r f1
do
echo $f1
done <"${1:-/dev/stdin}"
像这样的./test foo.csv
调用,它返回testing123
。
像这样的./test -f foo.csv
称为
unknown
testing123
这样称呼:
echo "testing123" | ./test.sh
或此
./test.sh <<< "testing123"
返回
./test.sh: line 6: $1 unbound variable
答案 0 :(得分:1)
更改
while true
到
while [ $# -ne 0 ]
当参数用尽时,代码将继续循环的下一次迭代,并尝试测试$1
(不存在)。由于您已完成set -eu
,因此引用未设置的变量会导致错误,并且脚本中止。