% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Saya berharap baris kedua bertindak sama.
% echo -e '1\n2' | parallel "bash -c 'echo :\$1' '' {}"
:1
:2
% echo -e '1\n2' | parallel bash -c 'echo :\$1' '' {}
%
Saya berharap baris kedua bertindak sama.
Jawaban:
parallel
menjalankan perintah di shell sudah (yang shell itu ditentukan oleh parallel
menggunakan heuristik (niat yang untuk memanggil shell sama seperti yang parallel
telah dipanggil dari ). Anda dapat mengatur $PARALLEL_SHELL
variabel untuk memperbaiki shell).
Ini bukan perintah yang Anda berikan parallel
seperti yang Anda inginkan untuk perintah env
atau xargs
, tetapi baris perintah shell (seperti yang Anda lakukan untuk eval
perintah).
Seperti untuk eval
, di parallel arg1 arg2
, parallel
adalah menyatukan argumen-argumen itu dengan spasi di antara (sehingga menjadi arg1 arg2
) dan string yang diteruskan ke <the-shell> -c
.
Untuk argumen yang diteruskan pada parallel
stdin, parallel
kutip mereka dalam format yang diharapkan oleh shell tertentu (tugas yang sulit dan rawan kesalahan itulah sebabnya Anda akan menemukan ada banyak bug yang diperbaiki di sekitar itu di parallel
Changelog ( beberapa masih belum diperbaiki pada 2017-03-06)) dan menambahkannya ke baris perintah itu.
Jadi misalnya, jika dipanggil dari dalam bash
,
echo "foo'bar" | parallel echo foo
Akan memiliki panggilan paralel bash -c
dengan echo foo foo\'bar
sebagai baris perintah. Dan jika dipanggil dari dalam rc
(atau dengan PARALLEL_SHELL=rc
) rc -c
dengan echo foo foo''''bar
.
Di Anda:
parallel bash -c 'echo :\$1' '' {}
parallel
menggabungkan argumen-argumen yang memberikan:
bash -c echo :$1 {}
Dan dengan {}
diperluas dan dikutip dalam format yang tepat untuk shell Anda menelepon parallel
dari, melewati itu untuk <that-shell> -c
yang akan memanggil bash -c echo
dengan :$1
di $0
dan perdebatan dalam $1
.
Ini bukan cara parallel
kerjanya. Di sini, Anda mungkin ingin:
printf '1\n2\n' | PARALLEL_SHELL=bash parallel 'echo :{}'
Untuk melihat apa yang parallel
terjadi, Anda dapat menjalankannya di bawah strace -fe execve
(atau yang setara di sistem Anda jika bukan Linux).
Di sini, Anda bisa menggunakan GNU xargs
alih-alih parallel
mendapatkan pemrosesan yang lebih sederhana lebih dekat dengan apa yang Anda harapkan:
printf '1\n2\n' | xargs -rn1 -P4 bash -c 'echo ":$1"' ''
Lihat juga diskusi di https://lists.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html
Perhatikan bahwa dalam bash -c 'echo foo' '' foo
, Anda membuat $0
string kosong untuk skrip inline itu. Saya akan menghindari itu karena itu $0
juga digunakan dalam pesan kesalahan. Membandingkan:
$ bash -c 'echo x > "$1"' '' /
: /: Is a directory
dengan.
$ bash -c 'echo x > "$1"' bash /
bash: /: Is a directory
Perhatikan juga bahwa membiarkan variabel yang tidak dikutip memiliki arti yang sangat khusus bash
dan yang echo
secara umum tidak dapat digunakan untuk data yang berubah-ubah.