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