Utk*_*tku 6 shell shell-script variable
我正在尝试调试我的 shell 脚本:
content_type='-H "Content-Type: application/json"'
curl $content_type -d "{"test": "test"}" example.com
Run Code Online (Sandbox Code Playgroud)
我了解到这并没有达到我的预期。在此脚本中,传递给curl(由于$content_type)的参数是:
-H"Content-Type:application/json"而不是(我所期望的):
-HContent-Type: application/json我知道我可以编写如下脚本:
content_type="Content-Type: application/json"
curl -H "$content_type" -d "{"test": "test"}" example.com
Run Code Online (Sandbox Code Playgroud)
它会以这种方式工作,但我想知道是否可以在单个变量中保存包含参数的多个空间。
对于第二个(工作)版本,如果我想排除内容类型,我需要删除两件事:-H和$content_type。
但是,我想知道是否可以将选项及其值放入单个实体中,以便排除/包含内容类型将导致删除/添加单个实体。
使用数组是不可移植的,因为 POSIX 中没有数组。
原因是分词。当我们定义content_type如下时:
content_type='-H "Content-Type: application/json"'
Run Code Online (Sandbox Code Playgroud)
它具有以下价值:
-H "Content-Type: application/json"
Run Code Online (Sandbox Code Playgroud)
当我们引用不带引号的变量(即,$content_type而不是"$content_type")时,扩展值将成为分词的主题。来自bash 手册的分词页面:
shell 扫描未出现在双引号内的参数扩展、命令替换和算术扩展的结果以进行分词。
来自同一页面:
shell 将 的每个字符视为
$IFS分隔符,并使用这些字符作为字段终止符将其他扩展的结果拆分为单词。如果 IFS 未设置,或其值恰好为<space><tab><newline>,则默认...
因此,-H "Content-Type: application/json"通过用作分隔符来分割<space><tab><newline>。这给了我们:
-H
"Content-Type:
application/json"
Run Code Online (Sandbox Code Playgroud)
复制吉尔斯答案中的相关部分:
\n\n\n\n\n如何将命令存储在变量中?
\n\n\xe2\x80\x9cCommand\xe2\x80\x9d 可以表示三件事:命令名称(作为可执行文件的名称,带或不带完整路径,或函数名称、内置函数或别名)、带参数的命令名,或一段 shell\n 代码。因此有不同的方法将它们存储在变量中。
\n\n如果您有命令名称,只需存储它并像往常一样使用带双引号的变量。
\n\nRun Code Online (Sandbox Code Playgroud)\n\ncommand_path="$1"\n\xe2\x80\xa6\n"$command_path" --option --message="hello world"\n如果您有一个带参数的命令,则问题与\n上面的文件名列表相同:这是一个字符串列表,而不是字符串。\n您不能仅将参数填充到单个字符串中\n 之间有空格,因为如果这样做,您将无法区分参数中的空格和分隔参数的空格。\n 如果您的 shell 有数组,则可以使用它们。
\n\nRun Code Online (Sandbox Code Playgroud)\n\ncmd=(/path/to/executable --option --message="hello world" --)\ncmd=("${cmd[@]}" "$file1" "$file2")\n"${cmd[@]}"\n如果您使用的 shell 没有数组怎么办?如果您不介意修改位置参数,您仍然可以使用它们。
\n\nRun Code Online (Sandbox Code Playgroud)\n\nset -- /path/to/executable --option --message="hello world" --\nset -- "$@" "$file1" "$file2"\n"$@"\n如果您需要存储复杂的 shell 命令(例如重定向、管道等)怎么办?或者如果您不想修改位置参数?然后您可以构建一个包含 \n 命令的字符串,并使用
\n\neval内置命令。Run Code Online (Sandbox Code Playgroud)\ncode=\'/path/to/executable --option --message="hello world" -- /path/to/file1 | grep "interesting stuff"\'\neval "$code"\n
不过,我建议任何人阅读吉尔斯的整个答案。它包含大量有用的信息。
\n| 归档时间: |
|
| 查看次数: |
1822 次 |
| 最近记录: |