% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
ฉันคาดหวังว่าบรรทัดที่สองจะทำหน้าที่เดียวกัน
% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
ฉันคาดหวังว่าบรรทัดที่สองจะทำหน้าที่เดียวกัน
คำตอบ:
parallelรันคำสั่งในเปลือกที่มีอยู่แล้ว (ซึ่งเปลือกมันจะถูกกำหนดโดยparallelใช้การวิเคราะห์พฤติกรรม (ความตั้งใจที่จะก่อให้เกิดการเป็นเปลือกเช่นเดียวกับคนที่parallelถูกเรียกจาก ). คุณสามารถตั้งค่า$PARALLEL_SHELLตัวแปรในการแก้ไขปัญหาเปลือก)
มันไม่ใช่คำสั่งที่คุณส่งให้parallelเหมือนอย่างที่คุณต้องการสำหรับenvหรือxargsคำสั่ง แต่เป็นบรรทัดคำสั่งเชลล์ (เช่นเดียวกับที่คุณทำกับevalคำสั่ง)
เหมือนevalในparallel arg1 arg2, parallelมีการเชื่อมโยงข้อโต้แย้งที่มีช่องว่างในระหว่าง (ดังนั้นมันจะกลายเป็นarg1 arg2) <the-shell> -cและสตริงที่ถูกส่งไปยัง
สำหรับข้อโต้แย้งที่ถูกส่งผ่านparallelstdin ให้parallelอ้างอิงคำพูดในรูปแบบที่เชลล์คาดหวังไว้ (เป็นงานที่ยากและมีข้อผิดพลาดซึ่งเป็นสาเหตุที่คุณจะพบว่ามีข้อบกพร่องมากมายที่แก้ไขรอบ ๆ ในparallelรายการของการเปลี่ยนแปลง () บางส่วนยังไม่ได้รับการแก้ไขตั้งแต่วันที่ 2017-03-06)) และผนวกเข้ากับบรรทัดคำสั่งนั้น
ดังนั้นสำหรับตัวอย่างเช่นถ้าเรียกจากภายในbash,
echo "foo'bar" | parallel echo foo
จะมีการเรียกแบบขนานbash -cพร้อมกับecho foo foo\'barเป็นบรรทัดคำสั่ง และถ้าเรียกจากภายในrc(หรือPARALLEL_SHELL=rc) ด้วยrc -cecho foo foo''''bar
ใน:
parallel bash -c 'echo :\$1' '' {}
parallel เชื่อมข้อขัดแย้งที่ให้:
bash -c echo :$1 {}
และด้วยการ{}ขยายและยกมาในรูปแบบที่เหมาะสมสำหรับเชลล์ที่คุณโทรหาparallelส่งผ่านสิ่ง<that-shell> -cที่จะเรียกbash -c echoด้วย:$1ใน$0และอาร์กิวเมนต์ปัจจุบัน$1มา
มันไม่parallelทำงาน ที่นี่คุณอาจต้องการ:
printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'
เพื่อดูว่ามีอะไรparallelคุณสามารถเรียกใช้ภายใต้strace -fe execve(หรือเทียบเท่าในระบบของคุณถ้าไม่ Linux)
ที่นี่คุณสามารถใช้ GNU xargsแทนparallelการประมวลผลที่ง่ายขึ้นใกล้กับสิ่งที่คุณคาดหวัง:
printf '1\n2\n' | xargs -rn1 -P4 bash -c 'echo ":$1"' ''
ดูการอภิปรายได้ที่https://lists.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html
โปรดทราบว่าbash -c 'echo foo' '' fooคุณกำลังสร้าง$0สตริงที่ว่างเปล่าสำหรับสคริปต์แบบอินไลน์ ฉันจะหลีกเลี่ยงสิ่งนั้นเช่นเดียวกับที่$0ใช้ในข้อความแสดงข้อผิดพลาด เปรียบเทียบ:
$ bash -c 'echo x > "$1"' '' /
: /: Is a directory
กับ
$ bash -c 'echo x > "$1"' bash /
bash: /: Is a directory
นอกจากนี้โปรดทราบว่าการคงไว้ซึ่งตัวแปรที่ไม่ได้ระบุไว้มีความหมายพิเศษมากbashและechoโดยทั่วไปไม่สามารถใช้สำหรับข้อมูลโดยพลการ