简单的 bash 脚本不起作用

简单的 bash 脚本不起作用

此脚本应将名称在命令行上作为参数提供的所有文件复制到用户主目录。如果未提供文件,则脚本应使用 read 来询问文件名,并将答案中提供的所有文件名复制到用户主目录。

if [ -z $1 ]
then
    echo provide filenames
    read $FILENAMES
else
    FILENAMES="$@"
fi

echo the following filenames have been provided: $FILENAMES
for i in $FILENAMES
do
    cp $i $HOME
done

如果我提供字符串形式的参数 - 它可以工作。但如果我提供“读取$FILENAMES” - 它不起作用。

导师在他的课程中展示了相同的解决方案,但没有展示它是如何工作的。 在此输入图像描述

更新在我输入文件名作为参数后,它给出空字符串并且没有将文件复制到 $HOME 位置

[dmytro@oc1726036122 ~]$ cd Desktop/
[dmytro@oc1726036122 Desktop]$ . totmp 
provide filenames
one two
the following filenames have been provided:
the following filenames have been provided:
[dmytro@oc1726036122 Desktop]$

答案1

声明read变量而不是读取它们。简而言之,删除其中的$内容read就可以了。

if [ -z $1 ]
then
    echo provide filenames
    read FILENAMES
else
    FILENAMES="$@"
fi

echo the following filenames have been provided: $FILENAMES
for i in $FILENAMES
do
    cp $i $HOME
done

编辑:我看到您使用source( .) 命令来运行脚本。

[dmytro@oc1726036122 Desktop]$ . totmp

对于这个特定的脚本来说可能没问题,但对于复杂的脚本永远不要这样做。否则,您将从该脚本中获取任何变量或函数到您的 shell 中。只需使用bash totmp

答案2

似乎阻碍您的问题是命令read不正确,传递给它的参数应该是变量名,因此应该在没有$($将扩展变量的内容,此时变量为空,所以结果是 a read,没有传递任何变量名。)

read FILENAMES

检查是否缺少第一个命令行参数还有另一个问题。如果它不存在,则将$1扩展为空(不是空字符串),这可能会导致命令出现问题[,因为在这种情况下您希望检查的内容[ -z ]实际上并不应该是有效的。[ -z "" ]简而言之,您需要引用该变量:

if [ -z "$1" ]

当您使用 bash 时,您也可以使用[[ ... ]],这通常更好,因为它是一个内部命令(在这种情况下,该命令应该在没有引号的情况下工作,但保留引号不会造成伤害并且看起来不错。)

(PS:这个脚本还有很多错误,它离最佳实践还很远,看到有人教这个我真的很震惊。不幸的是,似乎教授 bash 的门槛真的很低,而且手册也很复杂,直到你实际上理解得很好,所以我也不知道我对如何正确学习它有更好的建议。)☹️

答案3

read命令接受变量,但您已经引用了变量的值:

 #correct syntax
 read variable
 #wrong syntax
 read $variable

$variable是 的值variable,并且在脚本的开头,该值未设置/为空。

相关内容