shell 使用`bash -c`设置$PS4

esbemjvw  于 2023-04-07  发布在  Shell
关注(0)|答案(2)|浏览(232)

我正在尝试为bash -c命令设置$PS4。示例:

bash -xc 'PS4='$(date "+%s.%N ($LINENO) + ")'; echo ABC; echo XYZ'

我试过用各种方法来逃避引号、美元符号和括号,但都没有成功。
我期望的输出是这样的,它可以通过一个shell脚本获得,该脚本具有/bin/bash -x shebang和$PS4定义:

#!/bin/bash -x 

PS4='$(date "+%s.%N ($LINENO) + ")'
echo ABC
echo XYZ

其产生:

...
11527777373.733823550 (4) + echo ABC
11527777373.754886273 (5) + echo XYZ
...

如何实现类似的bash -c ...命令?

igetnqfo

igetnqfo1#

一种方法是使用$'...'引号,它允许嵌入单引号:

bash -xc $'PS4=\'+ $(date "+%s.%N ($LINENO) ")\'; echo ABC; echo XYZ'

如果你可以不使用纳秒分辨率,我建议使用\D提示符转义,而不是date

bash -xc $'PS4=\'+ \\D{%s} ($LINENO) \'; echo ABC; echo XYZ'

请注意,您可以通过环境传递值来简化引用,尽管出于安全原因,如果bash以root身份运行,则这将不起作用(bash将简单地忽略在环境中找到的任何PS4值)。

PS4='+ \D{%s} ($LINENO) ' bash -xc 'echo ABC; echo XYZ'
zc0qhyus

zc0qhyus2#

为了完整性(添加到already-quite-good answer from chepner),您可以使用带引号的heredoc将代码放入变量中而无需修改;在双引号的上下文中展开该变量将按字面意思传递其内容:

cmd=$(cat <<'EOF'
PS4='+ $(date "+%s.%N ($LINENO) ")'
echo ABC
echo XYZ
EOF
)

bash -xc "$cmd"

相关问题