Di antara alternatif berikut ...
dengan
eval
.comd="ls" eval "$comd"
dengan
source /dev/stdin
printf "ls" | source /dev/stdin
dengan
source /dev/stdin
dan( )
atau{ }
( printf "ls" ) | source /dev/stdin { printf "ls"; } | source /dev/stdin
(Ketika kita menjalankan
printf
di{ }
, apakah ada manfaat lain selain tidak menggunakan subkulit?)Apa perbedaan di antara mereka?
Mana yang lebih disukai?
Mana cara yang disukai untuk menjalankan perintah?
()
atau{}
?
bash
command-line
MS.Kim
sumber
sumber
Jawaban:
dari
bash manpage
:Tidak ada perbedaan antara dua cara.
Hanya ada satu catatan:
eval
menyatukan semua argumennya, yang kemudian dijalankan sebagai satu perintah.source
membaca isi file dan mengeksekusinya.eval
hanya dapat membangun perintah dari argumennya, bukanstdin
. Jadi Anda tidak bisa melakukan seperti ini:Contoh Anda memberikan hasil yang sama, tetapi tujuan
eval
dansource
berbeda.source
biasanya digunakan untuk menyediakan pustaka untuk skrip lain, sementaraeval
hanya digunakan untuk mengevaluasi perintah. Anda harus menghindari penggunaaneval
jika memungkinkan, karena tidak ada jaminan bahwa string yang diaktifkan bersih; kita harus melakukan beberapa pemeriksaan kewarasan,subshell
sebagai gantinya.Saat Anda menjalankan perintah sekuens di dalam kurung kurawal
{ }
, semua perintah dijalankan di shell saat ini , alih-alih sebuah subkulit (yang merupakan kasus jika Anda menjalankan di dalam tanda kurung (lihat referensi bash )).Menggunakan
subshell ( )
menggunakan lebih banyak sumber daya, tetapi lingkungan Anda saat ini tidak terpengaruh. Menggunakan{ }
menjalankan semua perintah di shell saat ini, sehingga lingkungan Anda terpengaruh. Tergantung pada tujuan Anda, Anda dapat memilih salah satunya.sumber
eval
dengansource
. Saya kira pertanyaannya adalah:eval "$cmd"
Setara denganecho "$cmd" | source /dev/stdin
. Pendapat saya saat ini adalah: ya.Perbedaan utama adalah bahwa formulir ke-2 dan ke-3 menggunakan pipa, yang akan memaksa bash untuk menjalankan perintah "sumber" dalam sebuah subkulit (kecuali jika lastpipe diatur, hanya tersedia dalam bash 4.2+), yang akan membuatnya cukup setara dengan :
Konsekuensinya adalah bahwa setiap variabel lingkungan yang ditetapkan oleh kode Anda akan hilang, jadi ini tidak akan berfungsi seperti yang diharapkan:
Untuk menjalankan perintah di shell saat ini, Anda dapat menggunakan substitusi proses:
Anda dapat menempatkan lebih banyak perintah di dalam tanda kurung menggunakan titik koma seperti biasa.
Jika Anda menghilangkan pipa dengan cara ini, saya percaya tidak ada perbedaan antara menggunakan "eval" dan "source". Anda harus memilih yang lebih mudah digunakan dalam kasus khusus Anda:
sumber
Sebagai pelengkap jawaban yang sudah diberikan:
Sebuah
source
setara dengan ...... adalah ...
Dalam hal
ls
tidak ada perbedaan yang signifikan.Tetapi dalam kasus perintah yang dimaksudkan untuk mempengaruhi lingkungan Anda saat ini (apa yang biasanya Anda maksudkan saat menggunakan
source
) varian ini akan melakukannya (seperti solusi pertama Andaeval
juga akan) sementara pendekatan kedua Anda hanya mempengaruhi lingkungan subkulit yang menang ' t tersedia setelah mengeksekusi baris kode Anda.sumber