簡體   English   中英

GNU Parallel和Bash函數:如何運行手冊中的簡單示例

[英]GNU Parallel and Bash functions: How to run the simple example from the manual

我正在嘗試學習GNU Parallel,因為我有一個案例,我認為我可以輕松地並行化bash函數。 所以在試圖學習的時候,我去了GNU Parallel手冊 ,里面有一個例子 ......但是我甚至無法讓它工作! 以機智:

(232) $ bash --version
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
(233) $ cat tpar.bash
#!/bin/bash

echo `which parallel`
doit() {
  echo Doing it for $1
  sleep 2
  echo Done with $1
}
export -f doit
parallel doit ::: 1 2 3
doubleit() {
  echo Doing it for $1 $2
  sleep 2
  echo Done with $1 $2
}
export -f doubleit
parallel doubleit ::: 1 2 3 ::: a b

(234) $ bash tpar.bash
/home/mathomp4/bin/parallel
doit: Command not found.
doit: Command not found.
doit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.

正如您所看到的,我甚至無法獲得運行的簡單示例。 因此,我可能正在做一些非常愚蠢和基本的事情......但我不知所措。

ETA:根據評論者的建議(chmod + x,set -vx):

(27) $ ./tpar.bash

echo `which parallel`
which parallel
++ which parallel
+ echo /home/mathomp4/bin/parallel
/home/mathomp4/bin/parallel

doit() {
  echo Doing it for $1
  sleep 2
  echo Done with $1
}
export -f doit
+ export -f doit
parallel doit ::: 1 2 3
+ parallel doit ::: 1 2 3
doit: Command not found.
doit: Command not found.
doit: Command not found.
doubleit() {
  echo Doing it for $1 $2
  sleep 2
  echo Done with $1 $2
}
export -f doubleit
+ export -f doubleit
parallel doubleit ::: 1 2 3 ::: a b
+ parallel doubleit ::: 1 2 3 ::: a b
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.
doubleit: Command not found.

ETA2:注意,我可以在腳本中調用'doit 1',比如說,它會做到這一點。 所以功能是有效的,它不是......導出的?

您無法從定義它的shell外部調用shell函數。 shell函數是shell中的一個概念。 parallel命令本身無法訪問它。

在bash中調用export -f doit通過環境導出函數,以便子進程將其捕獲。 但只有bash才能理解bash函數。 (宏)*子bash進程可以調用它,但不能調用其他程序,例如其他shell。

通過消息“未找到命令”,您的首選shell似乎是(t)csh。 你需要告訴parallel並調用bash。 parallel調用由SHELL環境變量SHELL指示的shell,因此將其設置為指向bash。

export SHELL=$(type -p bash)
doit () { … }
export -f doit
parallel doit ::: 1 2 3

如果您只想為執行parallel命令而不是腳本的其余部分設置SHELL

doit () { … }
export -f doit
SHELL=$(type -p bash) parallel doit ::: 1 2 3

我不確定如何處理遠程作業,除了--env=doit之外,你可能還需要傳遞--env=SHELL (請注意,這假設bash的路徑到處都是相同的)。

是的,這個奇怪之處應該在手冊中更加突出。 command參數的描述中有一個簡短的注釋,但它不是非常明確(它應該解釋command字與空格連接作為分隔符然后傳遞給$SHELL -c ),而SHELL不是甚至列在環境變量部分。 (我鼓勵你把這個報告為一個bug;我不是這樣做的,因為我幾乎沒有使用過這個程序。)

¹ 這是糟糕的設計,因為SHELL應該指示交互式命令行shell的用戶界面首選項,而不是更改程序的行為。

從版本20160722開始,您可以改為使用env_parallel

doit() { echo "$@"; }
echo world | env_parallel doit Hello

你只需要通過將它添加到.bashrc來激活env_parallel

env_parallel --install

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM