Jika saya lari
export TEST=foo
echo $TEST
Ini menghasilkan foo.
Jika saya lari
TEST=foo echo $TEST
Itu tidak. Bagaimana saya bisa mendapatkan fungsionalitas ini tanpa menggunakan ekspor atau skrip?
Jika saya lari
export TEST=foo
echo $TEST
Ini menghasilkan foo.
Jika saya lari
TEST=foo echo $TEST
Itu tidak. Bagaimana saya bisa mendapatkan fungsionalitas ini tanpa menggunakan ekspor atau skrip?
Jawaban:
Ini karena shell memperluas variabel dalam baris perintah sebelum benar-benar menjalankan perintah dan pada saat itu variabel tidak ada. Jika Anda menggunakan
TEST=foo; echo $TEST
ini akan bekerja.
exportakan membuat variabel muncul di lingkungan perintah yang dieksekusi selanjutnya (untuk tentang bagaimana ini bekerja di bash lihat help export). Jika Anda hanya perlu variabel untuk muncul di lingkungan satu perintah, gunakan apa yang Anda coba, yaitu:
TEST=foo your-application
$TESTsebelum baris perintah dieksekusi. Setelah echoberjalan (perhatikan juga bahwa echobiasanya akan menerjemahkan ke perintah built-in shell dan tidak ke /bin/echo) ia melihat set variabel di lingkungannya. Namun, echo $TESTtidak memberi tahu echountuk mengeluarkan isi variabel TESTdari lingkungannya. Ia memberi tahu shell untuk menjalankan echoargumen menjadi apa pun yang saat ini ada dalam variabel yang disebut TEST- dan itu adalah dua hal yang sangat berbeda.
var=value sh -c 'echo "$var"'?
"… $var …") tetapi tidak di dalam tanda kutip tunggal (misalnya, '… $var …'). Karena echo "$var"ada di dalam tanda kutip tunggal, seluruh string akan diteruskan ke sh -cshell ( ) baru tanpa ditafsirkan oleh shell interaktif luar. … (Lanjutan)
sh -ckulit anak baru ( ).
Saya menduga Anda ingin memiliki variabel shell untuk memiliki cakupan terbatas, daripada variabel lingkungan. Variabel lingkungan adalah daftar string yang diteruskan ke perintah ketika dieksekusi .
Di
var=value echo whatever
Anda meneruskan var=valuestring ke lingkungan yang menerima gema. Namun, echotidak melakukan apa-apa dengan daftar lingkungannya dan tetap di sebagian besar shell, echodibangun dan karenanya tidak dieksekusi .
Jika Anda telah menulis
var=value sh -c 'echo "$var"'
Itu akan menjadi masalah lain. Di sini, kita meneruskan var=valueke shperintah, dan shkebetulan menggunakan lingkungannya. Shell mengonversi masing-masing variabel yang mereka terima dari lingkungannya ke variabel shell, sehingga varvariabel lingkungan yang shditerima akan dikonversi ke $varvariabel, dan ketika itu diperluas di echobaris perintah itu, itu akan menjadi echo value. Karena lingkungan secara default diwarisi, echojuga akan menerima var=valuedi lingkungannya (atau akan jika itu dijalankan), tetapi sekali lagi, echotidak peduli dengan lingkungan.
Sekarang, jika seperti yang saya duga, yang Anda inginkan adalah membatasi ruang lingkup variabel shell, ada beberapa pendekatan yang mungkin.
Portably (Bourne dan POSIX):
(var=value; echo "1: $var"); echo "2: $var"
The (...) di atas memulai sub-shell (proses shell baru di sebagian besar shell), jadi variabel apa pun yang dideklarasikan hanya akan mempengaruhi sub-shell itu, jadi saya berharap kode di atas menghasilkan output "1: value" dan "2:" atau "2: apa pun-var-sudah-ditetapkan-sebelumnya".
Dengan sebagian besar shell mirip Bourne, Anda dapat menggunakan fungsi dan builtin "lokal":
f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"
Dengan zsh, Anda dapat menggunakan fungsi sebaris:
(){ local var=value; echo "1: $var"; }; echo "2: $var"
atau:
function { local var=value; echo "1: $var"; }; echo "2: $var"
Dengan bash dan zsh (tetapi bukan ash, pdksh atau AT&T ksh), trik ini juga berfungsi:
var=value eval 'echo "1: $var"'; echo "2: $var"
Varian yang bekerja dalam beberapa kerang lebih ( dash, mksh, yash) tapi tidak zsh(kecuali dalam sh/ kshemulasi):
var=value command eval 'echo "1: $var"'; echo "2: $var"
(menggunakan commanddi depan builtin khusus (di sini eval) di shell POSIX menghapus keistimewaan mereka (di sini bahwa penugasan variabel dari mereka tetap berlaku setelah mereka kembali))
Anda melakukannya dengan benar, tetapi sintaks bash adalah mudah untuk salah menafsirkan: Anda bisa berpikir bahwa echo $TESTmenyebabkan echountuk mengambil TESTenv var kemudian mencetaknya, tidak. Jadi diberikan
export TEST=123
kemudian
TEST=456 echo $TEST
melibatkan urutan berikut:
Shell mem-parsing seluruh baris perintah dan mengeksekusi semua penggantian variabel, sehingga baris perintah menjadi
TEST=456 echo 123Itu menciptakan vars temp ditetapkan sebelum perintah, sehingga menyimpan nilai saat ini TESTdan menimpanya dengan 456; baris perintah sekarang
echo 123Ini mengeksekusi perintah yang tersisa, yang dalam hal ini mencetak 123 ke stdout (jadi perintah shell yang tetap bahkan tidak menggunakan nilai temp dari TEST)
Ini mengembalikan nilai TEST
Gunakan printenv sebagai gantinya, karena tidak melibatkan substitusi variabel:
>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>
printenvbermanfaat untuk menguji / membuktikan konsep (berperilaku seperti naskah, berlawanan dengan echo)
Anda bisa membuatnya bekerja dengan menggunakan:
TEST=foo && echo $TEST
TEST=foodijalankan sebagai pernyataan terpisah - tidak hanya diatur dalam konteks echo.