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

我想通过这个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
        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元字符的文件名。