Bash进程替换存入变量异常:vimdiff脚本无内容显示问题排查
问题:vimdiff脚本无法正确对比多个URL内容
手动执行这条命令能正常对比两个URL的内容:
vimdiff -c 'set diffopt+=iwhite' <(curl -sS '...') <(curl -sS '...')
但写了个支持2-4个URL的脚本后,运行时vimdiff弹出两个空标签页,底部显示的文件名还一模一样(比如/proc/20228/fd/63)。脚本代码如下:
#!/bin/bash args=(-c 'set diffopt+=iwhite') while [ -n "$1" ]; do args+=("<(curl -sS "$1")") shift done vimdiff "${args[@]}"
问题根源
问题出在进程替换<(...)的生命周期上。把进程替换结果存进数组时,bash会在数组赋值完成后立刻关掉这些进程替换的文件描述符。等执行vimdiff "${args[@]}"时,这些临时文件已经没内容了,而且多个进程替换可能复用了同一个文件描述符,导致文件名重复。
修复方案
不能提前把进程替换存进数组,得在调用vimdiff的时候动态生成这些参数。修改后的脚本:
#!/bin/bash cmd=(vimdiff -c 'set diffopt+=iwhite') for url in "$@"; do cmd+=("<(curl -sS "$url")") done eval "${cmd[@]}"
或者用while循环的写法:
#!/bin/bash cmd=(vimdiff -c 'set diffopt+=iwhite') while [ -n "$1" ]; do cmd+=("<(curl -sS "$1")") shift done eval "${cmd[@]}"
这么改之后,进程替换的文件描述符会在vimdiff运行期间保持打开,curl的输出能被正常读取,每个URL对应的临时文件也不会复用描述符,标签页的文件名会正常区分开。
内容的提问来源于stack exchange,提问作者sjngm
相关产品推荐
相关产品推荐

