Dan*_*den 5 linux macos bash shell xargs
我正在尝试通过xargs
. 我在文件中创建了一个空分隔的命令列表,cmd_list.txt
然后尝试使用 6 个线程并行运行它们,如下所示:
cat cmd_list.txt | xargs -0 -P 6 -I % bash -c %
Run Code Online (Sandbox Code Playgroud)
但是,我收到以下错误:
bash: line 0: fg: no job control
Run Code Online (Sandbox Code Playgroud)
我已经缩小了与命令列表中各个命令的长度相关的问题。这是一个用于下载图像的人为长命令示例:
mkdir a-very-long-folder-de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8
wget --no-check-certificate --no-verbose -O a-very-long-folder-de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8/blah.jpg http://d4u3lqifjlxra.cloudfront.net/uploads/example/file/48/accordion.jpg
Run Code Online (Sandbox Code Playgroud)
仅wget
在没有文件列表和没有 的情况下单独运行命令xargs
,就可以正常工作。但是,在 bash 命令提示符下运行此命令(同样,没有文件列表)会失败并显示no job control error
:
echo "wget --no-check-certificate --no-verbose -O a-very-long-folder-de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8/blah.jpg http://d4u3lqifjlxra.cloudfront.net/uploads/example/file/48/accordion.jpg" | xargs -I % bash -c %
Run Code Online (Sandbox Code Playgroud)
如果我省略长文件夹名称并因此缩短命令,它可以正常工作:
echo "wget --no-check-certificate --no-verbose -O /tmp/blah.jpg http://d4u3lqifjlxra.cloudfront.net/uploads/example/file/48/accordion.jpg" | xargs -I % bash -c %
Run Code Online (Sandbox Code Playgroud)
xargs
有一个-s
(size) 参数可以更改命令行长度的最大大小,但我尝试将其增加到荒谬的大小(例如,16000)而没有任何影响。我认为问题可能与传入的字符串长度有关bash -c
,但以下命令也可以正常运行:
bash -c "wget --no-check-certificate --no-verbose -O a-very-long-folder-de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8/blah.jpg http://d4u3lqifjlxra.cloudfront.net/uploads/example/file/48/accordion.jpg"
Run Code Online (Sandbox Code Playgroud)
我知道还有其他选项可以并行运行命令,例如parallel
命令(/sf/answers/454849671/),但我仍然对修复我的设置或至少弄清楚在哪里很感兴趣出问题了。
我在 Mac OS X 10.10.1 (Yosemite) 上。
看起来解决方案是避免使用根据OS X xargs 手册页-I
的参数,其替换字符串有 255 字节的限制。相反,该参数可用,且没有 255 字节的限制。xargs
-J
所以我的命令看起来像:
echo "wget --no-check-certificate --no-verbose -O a-very-long-folder-de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8/blah.jpg http://d4u3lqifjlxra.cloudfront.net/uploads/example/file/48/accordion.jpg" | xargs -J % bash -c %
Run Code Online (Sandbox Code Playgroud)
然而,在上面的命令中,只有第一个空格之前的替换字符串部分被传递给 bash,因此 bash 尝试执行:
wget
Run Code Online (Sandbox Code Playgroud)
这显然会导致错误。我的解决方案是确保xargs
使用参数将命令解释为空分隔而不是空格分隔-0
,如下所示:
echo "wget --no-check-certificate --no-verbose -O a-very-long-folder-de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8de090952623b4865c2c34bd6330f8a423ed05ed8/blah.jpg http://d4u3lqifjlxra.cloudfront.net/uploads/example/file/48/accordion.jpg" | xargs -0 -J % bash -c %
Run Code Online (Sandbox Code Playgroud)
最后,这有效了!
感谢@CharlesDuffy 提供了大部分见解。不用感谢我的 OS X 版本,xargs
它对超过 255 字节限制的替换字符串的处理很差。
归档时间: |
|
查看次数: |
8143 次 |
最近记录: |