% 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
และสตริงที่ถูกส่งไปยัง
สำหรับข้อโต้แย้งที่ถูกส่งผ่านparallel
stdin ให้parallel
อ้างอิงคำพูดในรูปแบบที่เชลล์คาดหวังไว้ (เป็นงานที่ยากและมีข้อผิดพลาดซึ่งเป็นสาเหตุที่คุณจะพบว่ามีข้อบกพร่องมากมายที่แก้ไขรอบ ๆ ในparallel
รายการของการเปลี่ยนแปลง () บางส่วนยังไม่ได้รับการแก้ไขตั้งแต่วันที่ 2017-03-06)) และผนวกเข้ากับบรรทัดคำสั่งนั้น
ดังนั้นสำหรับตัวอย่างเช่นถ้าเรียกจากภายในbash
,
echo "foo'bar" | parallel echo foo
จะมีการเรียกแบบขนานbash -c
พร้อมกับecho foo foo\'bar
เป็นบรรทัดคำสั่ง และถ้าเรียกจากภายในrc
(หรือPARALLEL_SHELL=rc
) ด้วยrc -c
echo 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
โดยทั่วไปไม่สามารถใช้สำหรับข้อมูลโดยพลการ