Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash脚本中$1和“$1”之间的区别是什么?_Bash - Fatal编程技术网

bash脚本中$1和“$1”之间的区别是什么?

bash脚本中$1和“$1”之间的区别是什么?,bash,Bash,范例 我可以用1美元代替1美元吗?两者的区别是什么 用户=亚历山大和用户=亚历山大?谢谢 $A和$A之间的区别在于,在向程序和函数传递参数时,如何处理分词 想象一下在文件上工作的脚本,比如说移动文件: $ var="two words" $ function num_args() { echo "${#}"; } $ num_args $var 2 $ num_args "$var" 1 由于代码现在没有引号,此脚本将被破坏,因为它无法正确处理包含空格的文件路径 以下感谢@CharlesDuf

范例

我可以用1美元代替1美元吗?两者的区别是什么 用户=亚历山大和用户=亚历山大?谢谢

$A和$A之间的区别在于,在向程序和函数传递参数时,如何处理分词

想象一下在文件上工作的脚本,比如说移动文件:

$ var="two words"
$ function num_args() { echo "${#}"; }
$ num_args $var
2
$ num_args "$var"
1
由于代码现在没有引号,此脚本将被破坏,因为它无法正确处理包含空格的文件路径

以下感谢@CharlesDuffy

处理全球模式时的额外报价事项:

$ my-move "some file" other/path
或:


引号用作对参数进行分组的方式,而不管是否存在空格或其他特殊字符。通过演示,这里有一个案例,说明了两者的实质不同:

$ shopt -s failglob
$ var='[name]-with-brackets'
$ echo $var
bash: no match: [name]-with-brackets
$ echo "$var"
[name]-with-brackets
在上面的示例中,我们传递$foo时不带引号,它将bar作为参数1传递,将baz作为参数2传递,但当我们用引号传递它时,它将bar baz作为参数1传递


因此,虽然您可以编写不带引号的变量,例如$1,但通常最好将其用引号括起来,除非您特别希望将其视为几个独立的参数。

shell对不带引号的字符串的处理远远多于对带引号的字符串的处理,而不仅仅是在IFS中按空格或字符进行拆分,但也将每个拆分后组件扩展为一个全局,并且在99%的情况下,处理是不需要的。缺少引号可能会导致比任何其他单一类错误更多的条目。请避免在示例中使用所有caps变量名-请参阅相关POSIX规范的第四段,指定符合POSIX的shell和工具将仅修改其行为以响应所有caps变量名,以及使用至少一个小写字符保留名称以供应用程序使用。遵循此约定可避免类似于*/中的PATH以及突然无法运行外部命令的情况。顺便说一句,在引号起作用的地方,不仅仅是字符串可以在空格或IFS字符上拆分。运行set-“*”并比较echo$1和echo$1;或shopt-s failglob;集合-'[名称]-带括号';echo$1与带引号的相同值进行比较。@charlesduff谢谢。我可以用你的评论来扩展我的答案吗?当然可以。即使你真的想把一个字符串的内容当作几个独立的参数来处理,仅仅省略引号通常也不会起到预期的作用;讨论了这会失败的几种方式,以及为什么应该使用其他机制,例如数组。
#! /bin/sh
# my-move

src=${1}
dst=${2}

# ... do some fancy business logic here

mv ${src} ${dst}
$ my-move "some file" other/path
$ var='*'
$ num_args "$var"
1
$ num_args $var
60
$ shopt -s failglob
$ var='[name]-with-brackets'
$ echo $var
bash: no match: [name]-with-brackets
$ echo "$var"
[name]-with-brackets
$ foo="bar baz"
$ sh -c 'echo $1' worker $foo
bar
$ sh -c 'echo $1' worker "$foo"
bar baz