Shell 如何引用包含大量“的字符串”;和';?

Shell 如何引用包含大量“的字符串”;和';?,shell,Shell,我需要运行如下函数: process_del_netdevice() { curl "http://127.0.0.1:8080${1}monitor" --header \ "Content-Type: application/json" --header \ "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "device_del netdev-'$2'"}' curl "http://127.0.0.1:808

我需要运行如下函数:

process_del_netdevice()
{
    curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "device_del netdev-'$2'"}'

    curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "netdev_del '$2'"}'

    curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "chardev-remove char-'$2'"}'
}
process_del_netdevice()
{
    res="curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "device_del netdev-'$2'"}'"

    echo $res
}
但是我需要输出我已经运行的命令,所以我想编写如下代码:

process_del_netdevice()
{
    curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "device_del netdev-'$2'"}'

    curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "netdev_del '$2'"}'

    curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "chardev-remove char-'$2'"}'
}
process_del_netdevice()
{
    res="curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "device_del netdev-'$2'"}'"

    echo $res
}

但是提醒我错误,那么如何响应我运行的这个命令呢?谢谢~

这可以被正确引用,但那将变得非常不可读。我建议使用第二个函数进行打印和执行

execute_and_print() {
  "$@"
  printf '%q ' "$@"
  printf '\n'
}
在您的代码中:

    process_del_netdevice()
    {
    execute_and_print curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "device_del netdev-'$2'"}'

    execute_and_print curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "netdev_del '$2'"}'

    execute_and_print curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "chardev-remove char-'$2'"}'
}
正确的报价也可以通过以下方式实现:

for param in "$@"; do
  printf "'%s' " "$(printf '%s' "$param" | sed -e "s/'/'\\\\''/g")"
done
printf '\n'

这可以被正确引用,但这将变得非常不可读。我建议使用第二个函数进行打印和执行

execute_and_print() {
  "$@"
  printf '%q ' "$@"
  printf '\n'
}
在您的代码中:

    process_del_netdevice()
    {
    execute_and_print curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "device_del netdev-'$2'"}'

    execute_and_print curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "netdev_del '$2'"}'

    execute_and_print curl "http://127.0.0.1:8080${1}monitor" --header \
        "Content-Type: application/json" --header \
        "x-auth-token: $AUTH_TOKEN" -d '{"cmd": "chardev-remove char-'$2'"}'
}
正确的报价也可以通过以下方式实现:

for param in "$@"; do
  printf "'%s' " "$(printf '%s' "$param" | sed -e "s/'/'\\\\''/g")"
done
printf '\n'

使用
set-x
启用命令日志记录,使用
set+x
将其关闭。

;这是做这项工作的合适工具


要生成反映命令文本的带shell引号的字符串,可以使用bash和ksh扩展名
printf“%q”
,也可以依赖提供此类功能的第三方脚本语言。那么,考虑一下:

# needs Python, supported on all POSIX-y shells, output works on all POSIX shells
print_quoted() {
  python -c 'import sys, pipes; print(" ".join(pipes.quote(x) for x in sys.argv[1:]))' "$@"
}
……或者

# More efficient; needs bash or ksh; unusual inputs may result in outputs that only work
# on the same shell (ie. $''-quoted strings).
print_quoted() {
  printf '%q ' "$@"
  printf '\n'
}
一旦您选择了上述其中一项,就很容易在其他地方合并:

print_and_execute() {
  print_quoted "$@" >&2  # actually print
  "$@"                   # execute
}
首先——如果您只需要记录日志,请使用
set-x
启用shell的内置日志功能;这是做这项工作的合适工具


要生成反映命令文本的带shell引号的字符串,可以使用bash和ksh扩展名
printf“%q”
,也可以依赖提供此类功能的第三方脚本语言。那么,考虑一下:

# needs Python, supported on all POSIX-y shells, output works on all POSIX shells
print_quoted() {
  python -c 'import sys, pipes; print(" ".join(pipes.quote(x) for x in sys.argv[1:]))' "$@"
}
……或者

# More efficient; needs bash or ksh; unusual inputs may result in outputs that only work
# on the same shell (ie. $''-quoted strings).
print_quoted() {
  printf '%q ' "$@"
  printf '\n'
}
一旦您选择了上述其中一项,就很容易在其他地方合并:

print_and_execute() {
  print_quoted "$@" >&2  # actually print
  "$@"                   # execute
}

如果希望
eval
-安全引用,则需要:
printf“%q'”$@
。使用
'%s'
,您无法区分
echo“hello world”
echo“hello”“world”
之间的区别。但是,如果出于日志记录的目的,这并不能为您购买shell没有免费提供的任何东西。(这就是说--AFAICT,用户只是试图打印一个命令,根本不想立即执行它。如果这是真的,那么修复
%s
/
%q
问题,删除
“$@”
,可能需要记录生成的字符串需要在
eval
或等效上下文中使用才能执行,这将是最好的答案)。@CharlesDuffy这个问题没有用bash标记,所以我避免了
%q
,并添加了一个sed建议,以提高可读性。以及“需要输出我已运行的命令”明确提到了执行。虽然我混淆了顺序。问题是,如果不使用
%q
或其他等效项,则输出完全错误。它不能反映输出中正确的引用。如果要
eval
-安全引用,则需要:
printf'%q''$@
。使用
'%s'
,您无法区分
echo“hello world”
echo“hello”“world”
之间的区别。但是,如果出于日志记录的目的,这并不能买到shell没有免费提供给您的任何东西。(这就是说--AFAICT,用户只是试图打印一个命令,根本不想立即执行它。如果这是真的,那么修复
%s
/
%q
问题,删除
“$@”
,可能需要记录生成的字符串需要在
eval
或等效上下文中使用才能执行,这将是最好的答案)。@CharlesDuffy这个问题没有用bash标记,所以我避免了
%q
,并添加了一个sed建议,以提高可读性。以及“需要输出我已运行的命令”明确提到了执行。虽然我混淆了顺序。但问题是,如果不使用
%q
或其他等效项,则输出完全错误。它不能反映输出中正确的引用。这是直接相关的。顺便说一句,您的用法不能安全地引用不能直接替换为JSON strin的
$2
值考虑使用<代码> jq来生成所讨论的参数。(BTW)上下文是什么?一般来说,关于将shell命令作为字符串而不是数组处理的问题的最佳答案是“不要”。;提供足够的详细信息,让我们理解为什么这个答案不适用于您,也可能会引导一个更适用于您的用例的响应——例如,许多在bash中生成代码供bash使用的答案并不保证生成可以由其他非bash POSIX shell在pres中执行的代码不可打印的字符)是直接相关的。BTW,您的用法不安全地引用<代码> $ 2 < /代码>的值,它不能直接替换为JSON字符串。请考虑使用<代码> JQ> /代码>生成所讨论的参数。(顺便说一句,上下文是什么?一般来说,关于将shell命令作为字符串而不是数组处理的问题,最好的答案是“不要”;提供足够的详细信息,让我们理解为什么这个答案不适用于您,也可能会引导一个更适用于您的用例的响应——例如,许多在bash中生成代码供bash使用的答案并不保证生成可以由其他非bash POSIX shell在pres中执行的代码不可打印字符的数量)。