Bash 获得;工作-l“;显示实际命令,不带未展开的变量

Bash 获得;工作-l“;显示实际命令,不带未展开的变量,bash,shell,Bash,Shell,我执行了一个作为参数获取的后台进程,但在执行后没有成功获取进程的名称 我做了以下工作: #! /bin/bash filePath=$1 $filePath > log.txt & echo `jobs -l` 实际结果: [1]+ 2381 Running $filePath > log.txt & 预期结果: [1]+ 2381 Running /home/user/Desktop/script.sh > log.txt & 最好的答案是不要

我执行了一个作为参数获取的后台进程,但在执行后没有成功获取进程的名称

我做了以下工作:

#! /bin/bash

filePath=$1
$filePath > log.txt &
echo `jobs -l`
实际结果:

[1]+ 2381 Running $filePath > log.txt &
预期结果:

[1]+ 2381 Running /home/user/Desktop/script.sh > log.txt &

最好的答案是不要;作业控制是为交互使用而设计的功能,不能保证在非交互shell中可用,更不能保证以任何有用或有意义的方式运行。但是,如果您坚持,您可以使用
printf%q
生成变量展开后形式的
eval
-安全字符串,然后使用
eval
将其作为代码运行:

#!/bin/bash
printf -v logfile_q '%q' "${log:-log.txt}"  # use "$logfile", or default to log.txt
printf -v cmd_q '%q ' "$@"                  # quote our arguments into one eval-safe string

eval "$cmd_str >$logfile_q &"  # Parts that aren't hardcoded must be printf-q'd for safety.
jobs -l

注意,为了演示,我添加了一些额外的可配置性——在
eval
'd代码中使用
>log.txt
是可以的,但是使用
$logfile
是不安全的,因为如果
logfile=$'foo$(rm-rf~)\'$(rm-rf~)\''
(一个完全合法的文件名!)然后你会失去你的主目录。因此,需要在
eval
的参数中使用的任何变量都需要事先使用
printf%q
进行转义。

最好的答案是不要;作业控制是为交互使用而设计的功能,不能保证在非交互shell中可用,更不能保证以任何有用或有意义的方式运行。但是,如果您坚持,您可以使用
printf%q
生成变量展开后形式的
eval
-安全字符串,然后使用
eval
将其作为代码运行:

#!/bin/bash
printf -v logfile_q '%q' "${log:-log.txt}"  # use "$logfile", or default to log.txt
printf -v cmd_q '%q ' "$@"                  # quote our arguments into one eval-safe string

eval "$cmd_str >$logfile_q &"  # Parts that aren't hardcoded must be printf-q'd for safety.
jobs -l

注意,为了演示,我添加了一些额外的可配置性——在
eval
'd代码中使用
>log.txt
是可以的,但是使用
$logfile
是不安全的,因为如果
logfile=$'foo$(rm-rf~)\'$(rm-rf~)\''
(一个完全合法的文件名!)然后你会失去你的主目录。因此,任何需要在
eval
的参数中使用的变量都需要事先用
printf%q
进行转义。

/bin/bash,而不是
#/bin/bash
。顺便问一句,为什么会出现
回声
jobs-l
本身将其输出写入stdout,因此捕获它然后再次写入看起来毫无意义。顺便说一句,请注意,要使shebang产生任何效果,它必须是
#/bin/bash
,而不是
#/bin/bash
。顺便问一句,为什么会出现
回声
jobs-l
本身将其输出写入stdout,因此捕获它然后再次写入看起来毫无意义。如果不使用
printf%q
创建其参数,则使用
eval
会带来重大安全风险。查看是否未使用
printf%q
创建其参数,使用
eval
会带来严重的安全风险。看见