如何在执行命令之前回显命令
How to echo a command before executing it
我想在执行命令之前回显命令。此命令将字符串 'PROJECT_NAME' 替换为 file.yaml.
中的 'Hello world'
PROJECT_NAME="Hello world"
CMD="replace.py 'PROJECT_NAME' '${PROJECT_NAME}' file.yaml"
echo "${CMD}"
${CMD}
引用这个字符串的正确方法是什么,这样命令就会执行并且回显会显示命令?
注意变量 ${PROJECT_NAME} 的值包含空格,而 replace.py 恰好有 3 个参数。
我尝试转义所有引号 (\') 和美元符号 (\$)。我尝试用双引号 (") 交换单引号 (')。
通过一些引用,它会将 "Hello world" 中的每个单词视为一个单独的 arg,因此 replace.py 会因为 "world" 不是它期望的文件名而窒息。
我已阅读http://mywiki.wooledge.org/BashFAQ/050,但仍然无法理解。我不想重复命令或使用 set -x(因为在使用它时会打印 set +x 来关闭它)。
一种可能是使用数组而不是纯字符串,然后使用 printf
的 %q
格式在需要的地方重新添加引号 and/or 转义:
PROJECT_NAME="Hello world"
CMD=(replace.py 'PROJECT_NAME' "${PROJECT_NAME}" file.yaml)
printf "%q " "${CMD[@]}"; printf "\n"
"${CMD[@]}"
请注意,这可能与您创建数组时使用的 quoting/escaping 方法不同;例如,我尝试了上面的方法并打印了:
replace.py PROJECT_NAME Hello\ world file.yaml
相当于:
replace.py 'PROJECT_NAME' "Hello world" file.yaml
...只是编写相同命令的不同方式。
存储命令行并稍后执行它的正确方法可以通过两种方式完成:
- 使用BASH数组
- 使用BASH函数
1.使用 BASH 数组:
PROJECT_NAME="Hello world"
cmd=("replace.py" "PROJECT_NAME" "$PROJECT_NAME" "file.yaml")
printf "%q " "${cmd[@]}"; echo
"${cmd[@]}"
现在 运行 为:
bash ./script.sh
replace.py PROJECT_NAME Hello\ world file.yaml
注意 printf
的 %q
对 space 的转义。您可以直接从 shell 运行 此命令行也可以再次验证它,即
replace.py PROJECT_NAME Hello\ world file.yaml
2。使用函数:
#!/bin/bash
PROJECT_NAME="Hello world"
cmd() {
set -x
replace.py "PROJECT_NAME" "$PROJECT_NAME" "file.yaml"
set +x
}
cmd
现在 运行 为:
./script.sh
你会得到类似的输出:
+ replace.py PROJECT_NAME 'Hello world' file.yaml
...
...
set +x
您还可以 运行 此命令行:
replace.py PROJECT_NAME 'Hello world' file.yaml
我想在执行命令之前回显命令。此命令将字符串 'PROJECT_NAME' 替换为 file.yaml.
中的 'Hello world'PROJECT_NAME="Hello world"
CMD="replace.py 'PROJECT_NAME' '${PROJECT_NAME}' file.yaml"
echo "${CMD}"
${CMD}
引用这个字符串的正确方法是什么,这样命令就会执行并且回显会显示命令?
注意变量 ${PROJECT_NAME} 的值包含空格,而 replace.py 恰好有 3 个参数。
我尝试转义所有引号 (\') 和美元符号 (\$)。我尝试用双引号 (") 交换单引号 (')。
通过一些引用,它会将 "Hello world" 中的每个单词视为一个单独的 arg,因此 replace.py 会因为 "world" 不是它期望的文件名而窒息。
我已阅读http://mywiki.wooledge.org/BashFAQ/050,但仍然无法理解。我不想重复命令或使用 set -x(因为在使用它时会打印 set +x 来关闭它)。
一种可能是使用数组而不是纯字符串,然后使用 printf
的 %q
格式在需要的地方重新添加引号 and/or 转义:
PROJECT_NAME="Hello world"
CMD=(replace.py 'PROJECT_NAME' "${PROJECT_NAME}" file.yaml)
printf "%q " "${CMD[@]}"; printf "\n"
"${CMD[@]}"
请注意,这可能与您创建数组时使用的 quoting/escaping 方法不同;例如,我尝试了上面的方法并打印了:
replace.py PROJECT_NAME Hello\ world file.yaml
相当于:
replace.py 'PROJECT_NAME' "Hello world" file.yaml
...只是编写相同命令的不同方式。
存储命令行并稍后执行它的正确方法可以通过两种方式完成:
- 使用BASH数组
- 使用BASH函数
1.使用 BASH 数组:
PROJECT_NAME="Hello world"
cmd=("replace.py" "PROJECT_NAME" "$PROJECT_NAME" "file.yaml")
printf "%q " "${cmd[@]}"; echo
"${cmd[@]}"
现在 运行 为:
bash ./script.sh
replace.py PROJECT_NAME Hello\ world file.yaml
注意 printf
的 %q
对 space 的转义。您可以直接从 shell 运行 此命令行也可以再次验证它,即
replace.py PROJECT_NAME Hello\ world file.yaml
2。使用函数:
#!/bin/bash
PROJECT_NAME="Hello world"
cmd() {
set -x
replace.py "PROJECT_NAME" "$PROJECT_NAME" "file.yaml"
set +x
}
cmd
现在 运行 为:
./script.sh
你会得到类似的输出:
+ replace.py PROJECT_NAME 'Hello world' file.yaml
...
...
set +x
您还可以 运行 此命令行:
replace.py PROJECT_NAME 'Hello world' file.yaml