Memahami backtick (`)

35

Saya mencoba perintah

$ b=5; echo `$b`;
-bash: 5: command not found

tetapi tidak mencetak 5 sebagaimana mestinya. Apa yang kulewatkan di sini?

Apa arti `(backquote / backtick) dalam perintah? tampaknya mengatakan bahwa `mengevaluasi perintah di dalam dan menggantinya dengan output.

coolcric
sumber
8
Perhatikan bahwa backticks tidak disarankan karena Anda akan kehilangan kemampuan untuk melakukan penggantian eksekusi bersarang. Insetad, $ (somecommand) lebih disukai. Saya ingin meningkatkan keterbacaan.
Tommy
6
@Tommy, Tidak, backticks bisa disarangkan, tapi itu menjadi mimpi buruk, terutama ketika mengutip ganda juga.
Stéphane Chazelas

Jawaban:

52

Teks di antara backtick dieksekusi dan digantikan oleh output dari perintah (minus karakter garis belakang tertinggal, dan berhati-hatilah bahwa perilaku shell bervariasi ketika ada karakter NUL dalam output). Itu disebut substitusi perintah karena diganti dengan output dari perintah. Jadi jika Anda ingin mencetak 5, Anda tidak dapat menggunakan backticks, Anda dapat menggunakan tanda kutip, suka echo "$b"atau hanya menjatuhkan kutipan dan gunakan echo $b.

Seperti yang Anda lihat, karena $bberisi 5, ketika menggunakan backticks bashsedang mencoba menjalankan perintah 5dan karena tidak ada perintah seperti itu, gagal dengan pesan kesalahan.

Untuk memahami cara kerja backticks, coba jalankan ini:

$ A=`cat /etc/passwd | head -n1`
$ echo "$A"

cat /etc/passwd |head -n1harus mencetak baris pertama /etc/passwdfile. Tapi karena kami menggunakan backticks, itu tidak mencetak ini di konsol. Sebaliknya itu disimpan dalam Avariabel. Anda dapat mengulangi $Ahal ini. Perhatikan bahwa cara mencetak baris pertama yang lebih efisien adalah dengan menggunakan perintah, head -n1 /etc/passwdtetapi saya ingin menunjukkan bahwa ekspresi di dalam backticks tidak harus sederhana.

Jadi jika baris pertama dari / etc / passwd adalah root:x:0:0:root:/root:/bin/bash, perintah pertama akan diganti secara dinamis dengan bash to A="root:x:0:0:root:/root:/bin/bash".

Perhatikan bahwa sintaks ini dari shell Bourne. Mengutip dan melarikan diri dengan cepat menjadi mimpi buruk dengan itu terutama ketika Anda mulai bersarang. Ksh memperkenalkan $(...)alternatif yang sekarang distandarisasi ( POSIX ) dan didukung oleh semua shell (bahkan shell Bourne dari Unix v9). Jadi, Anda harus menggunakannya $(...)sebagai gantinya saat ini kecuali Anda harus portabel untuk cangkang Bourne yang sangat tua.

Perhatikan juga bahwa output dari `...`dan $(...)tunduk pada pemisahan kata dan pembuatan nama file seperti halnya ekspansi variabel (dalam zsh, hanya pemisahan kata), jadi umumnya perlu dikutip dalam konteks daftar.

Krzysztof Adamski
sumber
1
Hai @ Krzysztof, itu sangat membantu! "Karena $ b mengandung 5, bash mencoba menjalankan perintah 5" adalah persis apa yang saya cari
coolcric
you can use quotation marks, like echo "$b"=> apakah "" melakukan sesuatu yang istimewa? Tampaknya echo $bakan berhasil juga.
Tootsie Rolls
@Anita: Secara umum tanda kutip melakukan beberapa hal khusus (itu mengubah cara karakter khusus diperlakukan - terutama spasi putih) tetapi dalam kasus ini, mereka dapat dijatuhkan tanpa banyak masalah. Ini karena tidak ada karakter khusus yang digunakan dan echoperintah tidak peduli dengan jumlah argumen yang didapat sehingga jika bmemiliki beberapa spasi di dalamnya, ia akan mendapatkan beberapa argumen dan masih akan mencetaknya. Ini mungkin tidak berlaku untuk perintah lain (terutama ketika variabel tidak diatur) jadi saya cenderung selalu mengelilingi variabel dengan tanda kutip.
Krzysztof Adamski
alangkah baiknya jika (POSIX)akan menjadi tautan ke standar yang sebenarnya.
erikbwork
1
@ erikb85: Catatan ini tidak ditambahkan oleh saya tetapi saya telah mengeditnya dengan tautan seperti yang Anda sarankan :)
Krzysztof Adamski
11

Backtick melakukan persis seperti yang Anda katakan. Anda telah menetapkan variabel ke integer. Ketika Anda meletakkan variabel itu di dalam backticks, bash akan mencoba menjalankannya sebagai perintah. Karena ini bukan perintah, Anda mendapatkan kesalahan yang Anda lihat.

Yang ingin Anda lakukan hanyalah:

$ b=5; echo $b

Untuk memahami backticks lebih baik, bandingkan dengan:

$ b=5; a=`echo $b`; echo $a
  5
terdon
sumber
8

Selangkah demi selangkah, baris Anda harus menjelaskannya.

$ b=5; echo `$b`;
  1. set variabel b menjadi 5
  2. mengevaluasi $b(berjalan secara efektif5 )
  3. echoadalah hasil evaluasi di atas.

Jadi ya, output yang Anda dapatkan diharapkan. Anda mengevaluasi konten variabel, bukan perintah yang sebenarnya Anda pikirkan. Semua yang Anda masukkan ke dalam backticks dievaluasi secara simplay (dijalankan) di shell (sub) baru.

gertvdijk
sumber
hai @ gertvdijk, terima kasih untuk kiriman Anda! Saya berpikir bahwa `mengembalikan apa pun yang tersisa setelah mengevaluasi isinya. Jadi, saya pikir `$ b 'akan mengembalikan 5 untuk gema untuk mencetaknya
coolcric