Bash 为什么回音失败?
我想通过这个bash创建许多新的bash脚本。这是我的密码Bash 为什么回音失败?,bash,Bash,我想通过这个bash创建许多新的bash脚本。这是我的密码 #!/bin/bash # create bash shell automatically for file in "$*" do if [ ! -e "$file" ] then touch $file chmod u+x $file echo "#!/bin/bash" >> $file echo "# " >> $file
#!/bin/bash
# create bash shell automatically
for file in "$*"
do
if [ ! -e "$file" ]
then
touch $file
chmod u+x $file
echo "#!/bin/bash" >> $file
echo "# " >> $file
echo "create success"
fi
done
if [ $# \> 1 ]
then
echo "$# shell files are created!"
else
echo "$# shell is created!"
fi
当我像这样运行此脚本时:
./create_shell test1 test2 test3
航站楼说:
"line9:ambiguous redirect"
"line10:ambiguous redirect"
这是什么意思?“$*”是一个字符串,而不是参数数组。你可以这样做
fileArr=($*)
for file in ${fileArr[@]}
do you things
“$*”周围的引号将阻止bash将传递的参数解析为单个标记。循环将在传递所有参数的情况下执行一次(即,如果运行
test.sh one-two-three
,则echo命令将尝试重定向到“one-two-three”)。只需删除引号。问题来自于使用$*
,无论是引用还是取消引用。迭代位置参数的正确方法是使用“$@”
,请注意双引号
for file in "$@"; do
: ...
done
甚至夸张地说:
for file do
: ...
done
您从bash
获得错误消息,因为bash
查看$file
的内容没有扩展到一个单词,而是扩展到三个单独的单词test1
,test2
,test3
。尝试:
a='1 2 3'
echo 1 >> $a
看看会发生什么
更不用说你破坏了使用
“$@”
的唯一原因。为了使该构造能够工作,如果不希望调用split+glob
运算符,还必须在派生自该构造的变量周围加上双引号 [$\35;\>1]
不是有效的测试。使用[
,您使用-gt
进行数字“大于”比较。这是否会退化为一个不明确的重定向不太清楚;第9行在该重定向之前。您确定代码中的所有间距都与问题中所示的完全一致吗?是的。我多次检查使用$@
而不是$*
@JonathanLeffler:否,[$\35;\>1]
在bash
中有效。它是[…]
中的字符串比较运算符。这里对
进行了转义,以防止shell将其视为重定向运算符,因为您使用的是“$*”
,文件
中的值是test1 test2 test3
。当您使用echo“xxxx”>$file
展开该值时,Bash会感到不安。您可以通过运行一个参数来演示:一切正常。如果您引用变量:echo“xxx”>“$file”
,则一切正常。如果您使用“$@”
你会没事的。不,正确的解决方案是使用“$@”
而不是“$*”
。不,不要删除引号,这恰恰是错误的做法!这将阻止脚本使用包含shell元字符的文件名。