Dalam shell yang diberikan, biasanya saya akan menetapkan variabel atau variabel dan kemudian menjalankan perintah. Baru-baru ini saya belajar tentang konsep menambahkan definisi variabel ke sebuah perintah:
FOO=bar somecommand someargs
Ini berfungsi ... agak. Itu tidak berfungsi ketika Anda mengubah variabel LC_ * (yang tampaknya memengaruhi perintah, tetapi tidak argumennya, misalnya, rentang char '[az]') atau ketika memipitkan output ke perintah lain dengan demikian:
FOO=bar somecommand someargs | somecommand2 # somecommand2 is unaware of FOO
Saya dapat menambahkan somecommand2 dengan "FOO = bar" juga, yang berfungsi, tetapi yang menambahkan duplikasi yang tidak diinginkan, dan itu tidak membantu dengan argumen yang ditafsirkan tergantung pada variabel (misalnya, '[az]').
Jadi, apa cara yang baik untuk melakukan ini pada satu baris?
Saya sedang memikirkan sesuatu berdasarkan urutan:
FOO=bar (somecommand someargs | somecommand2) # Doesn't actually work
Saya mendapat banyak jawaban bagus! Tujuannya adalah untuk membuat ini satu-liner, lebih disukai tanpa menggunakan "ekspor". Metode menggunakan panggilan ke Bash adalah yang terbaik secara keseluruhan, meskipun versi kurung dengan "ekspor" di dalamnya sedikit lebih kompak. Metode menggunakan redirection bukan pipa juga menarik.
sumber
(T=$(date) echo $T)
akan bekerjaJawaban:
sumber
somecommand
sudo Anda, Anda harus memberikan sudo-E
flag untuk meneruskan variabel. Karena variabel dapat memperkenalkan kerentanan. stackoverflow.com/a/8633575/1695680FOO_X=foox bash -c 'echo $FOO_X'
berfungsi seperti yang diharapkan tetapi dengan nama var tertentu gagal:DYLD_X=foox bash -c 'echo $DYLD_X'
gema kosong. keduanya bekerja menggunakaneval
bukanbash -c
Bagaimana dengan mengekspor variabel, tetapi hanya di dalam subkulit ?:
Keith ada benarnya, untuk mengeksekusi perintah tanpa syarat, lakukan ini:
sumber
;
daripada&&
; tidak mungkinexport FOO=bar
akan gagal.&&
mengeksekusi perintah kiri, kemudian mengeksekusi perintah kanan hanya jika perintah kiri berhasil.;
mengeksekusi kedua perintah tanpa syarat. Windows Batch (cmd.exe
) setara;
adalah&
.(FOO=XXX ; echo FOO=$FOO) ; echo FOO=$FOO
hasilFOO=XXX\nFOO=\n
.source
(alias.
) dalam kasus itu? Juga, backticks tidak boleh digunakan lagi hari ini dan ini adalah salah satu alasan mengapa, menggunakan$(command)
waaaaay lebih aman.bash
tetapi bisa menjadi sesuatu yang lain, misalnyadash
) dan saya tidak mengalami kesulitan jika saya harus menggunakan tanda kutip dalam perintah args (someargs
).Anda juga dapat menggunakan
eval
:Karena jawaban dengan
eval
ini sepertinya tidak menyenangkan semua orang, izinkan saya mengklarifikasi sesuatu: ketika digunakan sebagai tulisan, dengan tanda kutip tunggal , itu sangat aman. Itu bagus karena tidak akan meluncurkan proses eksternal (seperti jawaban yang diterima) juga tidak akan menjalankan perintah dalam subkulit tambahan (seperti jawaban lainnya).Ketika kita mendapatkan beberapa pandangan reguler, mungkin baik untuk memberikan alternatif
eval
yang akan menyenangkan semua orang, dan memiliki semua manfaat (dan mungkin bahkan lebih!) Darieval
"trik" cepat ini . Cukup gunakan fungsi! Tetapkan fungsi dengan semua perintah Anda:dan jalankan dengan variabel lingkungan Anda seperti ini:
sumber
eval
.eval
adalah kejahatan tanpa memahami apa yang jahat tentangeval
. Dan mungkin Anda tidak benar-benar memahami jawaban ini (dan benar-benar tidak ada yang salah dengan itu). Pada tingkat yang sama: apakah Anda akan mengatakan ituls
buruk karenafor file in $(ls)
itu, buruk? (dan ya, Anda juga tidak memilih jawaban yang diterima, dan Anda juga tidak meninggalkan komentar). SO terkadang merupakan tempat yang aneh dan absurd.eval
adalah jahat tanpa memahami apa yang jahat tentangeval
, saya mengacu pada kalimat Anda: Jawaban ini tidak memiliki semua peringatan dan penjelasan yang diperlukan ketika berbicara tentangeval
.eval
tidak buruk atau berbahaya; tidak lebih daribash -c
.eval
. Dalam jawaban yang disediakan args telah dikutip tunggal melindungi dari ekspansi variabel, jadi saya tidak melihat masalah dengan jawabannya.eval
adalah masalah keamanan secara umum (sepertibash -c
tapi kurang jelas), sehingga bahaya harus disebutkan dalam jawaban yang mengusulkan penggunaannya. Pengguna yang ceroboh dapat mengambil jawabannya (FOO=bar eval …
) dan menerapkannya pada situasi mereka sehingga menimbulkan masalah. Tetapi jelas lebih penting bagi penjawab untuk mencari tahu apakah saya menurunkan jawaban dan / atau jawaban lain daripada memperbaiki apa pun. Seperti yang saya tulis sebelumnya, keadilan seharusnya tidak menjadi perhatian utama; menjadi tidak lebih buruk daripada jawaban yang diberikan lainnya juga terlepas.Gunakan
env
.Sebagai contoh
env FOO=BAR command
,. Perhatikan bahwa variabel lingkungan akan dipulihkan / tidak berubah lagi ketikacommand
selesai dijalankan.Berhati-hatilah dengan substitusi shell yang terjadi, yaitu jika Anda ingin referensi
$FOO
secara eksplisit pada baris perintah yang sama, Anda mungkin perlu menghindarinya sehingga interpreter shell Anda tidak melakukan substitusi sebelum dijalankanenv
.sumber
Gunakan skrip shell:
sumber
export
; jika tidak$FOO
akan menjadi variabel shell, bukan variabel lingkungan, dan karenanya tidak terlihatsomecommand
atausomecommand2
.