【问题标题】:Bash trap with variable expansion?具有可变扩展的 Bash 陷阱?
【发布时间】:2018-03-25 20:55:32
【问题描述】:

根据这个我不允许评论的问题:

Is it necessary to specify traps other than EXIT?

恕我直言,这是一个不完整的答案,因为它不涵盖以下常见情况:

TEMPDIR_OR_FILE=$(mktemp [ some switches and params and an XXX pattern] )
# ...so we want trap to do rm -rf ${TEMPDIR_OR_FILE}

给出的例子是:

# reset
trap 'excode=$?; cmd; trap - EXIT; echo $excode' EXIT HUP INT QUIT PIPE TERM

# ignore
trap 'excode=$?; trap "" EXIT; cmd; echo $excode' EXIT HUP INT QUIT PIPE TERM

这里的问题是单引号阻止你扩展${TEMPDIR_OR_FILE}

我认为复杂的是变量扩展的时间。我需要立即扩展${TEMPDIR_OR_FILE},但其他项目可能需要等到陷阱执行完毕。我该如何进行这项工作?

【问题讨论】:

  • 顺便说一句——全大写的名称用于对操作系统或系统有意义的变量,而具有至少一个小写字符的名称保留给应用程序使用并保证不会修改行为POSIX 指定的工具。见pubs.opengroup.org/onlinepubs/9699919799/basedefs/…,第四段。
  • 也就是说,为什么你想在定义陷阱时扩展TEMPDIR_OR_FILE,而不是在它执行时?稍后在执行时执行此操作(通过将定义放在外部单引号内)将让您更改正在使用的临时文件。
  • 根据我的经验,这不是问题。此类变量通常设置一次,甚至可能设置为只读,然后用于程序的其余部分。延迟扩展不会改变任何东西。为什么需要尽快解析?我可能会解决一些问题,但对于增加维护问题犹豫不决。

标签: bash


【解决方案1】:

最佳实践:在执行时展开

简单案例

你担心的代码,

trap 'EXIT' 'rm -f "$TEMPDIR_OR_FILE"'

...确实有效;它只是在陷阱运行时查找TEMPDIR_OR_FILE,而不是在定义时查找。这并没有错:当陷阱运行时是查看临时文件定义的最佳时间,因为这样脚本的其余部分可以在执行期间适当地更改这些定义。 p>

花哨:处理任意数量的临时文件

考虑以下几点:

declare -A tempfiles=( )
cleanup() { (( ${#tempfiles[@]} )) && rm -rf -- "${!tempfiles[@]}"; }
trap 'cleanup' EXIT

# ...do some stuff...
tempfiles[something]=$(mktemp -t -d something.XXXXXX)
echo "hello" >"${tempfiles[something]}/greeting"

# ...do more stuff...
tempfiles[something_else]=$(mktemp -t something_else.XXXXXX)
if [[ $keep_something_else ]]; then
  # the user wants us to keep this temporary file! remove it from deletion list
  unset tempfiles[keep_something_else]
fi

通过上面,你定义了你的清理函数只需要一次,并且不需要知道你当时的临时目录;当您退出时,您会查找存在的列表然后


字面答案:在定义时扩展

在大多数情况下,最好在执行陷阱时扩展变量,而不是在定义时。但是,您要求以另一种方式进行。

要做到这一点安全,请使用printf %q 生成文件名的eval-安全版本,并在定义陷阱时用双引号将其展开。

printf -v tempdir_or_file_q '%q' "$TEMPDIR_OR_FILE"
trap 'retval=$?; rm -rf '"${tempdir_or_file_q}"'; exit "$retval"'

请注意,我们在定义时引用要扩展的变量之前结束初始单引号,用双引号将其扩展,结束这些双引号并在之后切换回单引号。

【讨论】:

    猜你喜欢
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 2018-04-11
    • 1970-01-01
    相关资源
    最近更新 更多