Apa perbedaan antara $ (barang) dan `barang`?


265

Ada dua sintaks untuk substitusi perintah: dengan dolar-tanda kurung dan dengan backticks. Berjalan top -p $(pidof init)dan top -p `pidof init`memberikan hasil yang sama. Apakah kedua cara ini melakukan hal yang sama, atau adakah perbedaan?


18

43
Untuk sesaat saya pikir ini adalah pertanyaan jQuery.
David Murdoch

Hasilnya mungkin tergantung pada shell - beberapa mendukung keduanya.
artdanil

Jawaban:


360

Backquote gaya lama ` `memang memperlakukan backslash dan bersarang sedikit berbeda. Gaya baru $()mengartikan semuanya ( )sebagai perintah.

echo $(uname | $(echo cat))
Linux

echo `uname | `echo cat``
bash: command substitution: line 2: syntax error: unexpected end of file
echo cat

berfungsi jika backquotes bersarang lolos:

echo `uname | \`echo cat\``
Linux

backslash menyenangkan:

echo $(echo '\\')
\\

echo `echo '\\'`
\

Gaya baru ini $()berlaku untuk semua shell yang sesuai dengan POSIX .
Seperti yang ditunjukkan mouviciel , gaya lama ` `mungkin diperlukan untuk kulit kerang yang lebih tua.

Terlepas dari sudut pandang teknis, gaya lama ` `juga memiliki kelemahan visual:

  • Sulit untuk diperhatikan: I like $(program) better than `program`
  • Mudah bingung dengan satu kutipan: '`'`''`''`'`''`'
  • Tidak mudah untuk mengetik (mungkin bahkan tidak pada tata letak keyboard standar)

(dan menggunakan SE ` `untuk tujuan sendiri, itu adalah rasa sakit menulis jawaban ini :)


10
Satu-satunya hal yang akan saya tambahkan, adalah bahwa saya memanggil '(' paren, bukan braket (yang '[').
Kendall Helmstetter Gelner

@ Kendall: dan di sini saya pikir '{' adalah braket kiri selama bertahun-tahun ...
SamB

5
@ Sam: { }biasanya disebut "kurung keriting" atau "kurung kurawal" en.wikipedia.org/wiki/Braces_(punctuation)#Braces
Jørn Schou-Rode

2
Saya juga menyebut '{' sebagai kurung kurawal. Meskipun sepertinya aneh, Anda perlu menambahkan tanda "keriting" jika Anda menyebut tanda kurung lainnya ... Saya kira itu hanya karena mereka benar-benar menggulung.
Kendall Helmstetter Gelner

1
@slim Saya tidak tahu pada keyboard AS / Inggris, tetapi pada keyboard Spanyol `adalah kunci mati, jadi saya harus mengetikkan backtick ganda (sesuatu yang biasanya saya lupa saya bisa melakukannya) atau backtick lalu spasi, yang merupakan rasa sakit.
Darkhogg

41

Perbedaan jelas yang saya amati adalah bahwa Anda tidak dapat membuat sarang backtick sementara Anda bisa bersarang $(). Mungkin keduanya ada karena alasan warisan. Demikian pula, perintah .dan sourceadalah sinonim.


10
Beberapa cangkang yang diturunkan dari Bourne tidak mengenali source. Dash adalah salah satu contohnya.
Dennis Williamson

14
Itu tidak benar. Anda dapat bersarang backtick ke level apa pun, hanya dengan lebih menyakitkan. Perhatikan bahwa kedua $(...)dan `...`standar (yang terakhir yang usang) sementara .standar tapi tidaksource
Stéphane Chazelas

3
Koreksi, hanya di (t)cshmereka tidak bisa bersarang. (t)cshtidak mendukung $(...)sekalipun. Mereka memang mendukung source(dan tidak .).
Stéphane Chazelas

28

$()tidak bekerja dengan shell Bourne lama. Tapi sudah bertahun-tahun sejak saya bekerja dengan shell Bourne tua.


Umur tahun 1970-an dan awal 1980-an, benar?
Christopher

6

Catatan lain, $()akan menggunakan lebih banyak sumber daya sistem daripada menggunakan backticks, tetapi sedikit lebih cepat.

Dalam Menguasai scripting shell Unix , Randal K. Michael telah melakukan tes dalam bab bernama "24 Cara untuk Memproses File Baris-demi-Baris".


2
Klaim ini tidak masuk akal. Tidak ada alasan mengapa itu harus lebih cepat karena hanya menggunakan notasi yang berbeda untuk parser.
schily

@ Schily: Mungkin, saya hanya mengutip dari buku, Anda bisa membacanya untuk lebih jelasnya.
cuonglm

3
Saya cenderung setuju dengan @schily ... mengapa dibutuhkan lebih banyak sumber daya?
Wildcard

2
@Wildcard, saya kira itu karena $()membuat skrip Anda satu byte lebih besar daripada jika digunakan `(dengan asumsi Anda tidak membuat sarang dan tidak menggunakan backslash di dalamnya). Mengenai yang mana akan lebih cepat untuk diuraikan, itu akan bervariasi di antara cangkang dan tidak relevan jika diabaikan dibandingkan dengan biaya pembuatan pipa dan percabangan proses yang memerlukan substitusi.
Stéphane Chazelas

5

Untuk menambahkan apa yang orang lain katakan di sini, Anda dapat menggunakan backticks untuk mensimulasikan komentar sebaris:

echo foo `# I'm a comment!` bar

Outputnya adalah: foo bar.

Lihat yang berikut untuk informasi lebih lanjut: https://stackoverflow.com/a/12797512 (Perhatikan juga komentar di bawah posting itu.)


1

The $()sintaks tidak akan bekerja dengan shell Bourne tua.
Dengan cangkang yang lebih baru ` `dan $()setara tetapi $()jauh lebih mudah digunakan ketika Anda perlu membuat banyak perintah.

Misalnya :

echo $(basename $(dirname $(dirname /var/adm/sw/save )))

lebih mudah untuk mengetik dan debug daripada:

echo `basename \`dirname \\\`dirname /var/adm/sw/save \\\`\``

1
Sementara $ () mungkin terlihat bagus, itu menyakitkan ketika menerapkan parser terkait karena membutuhkan parser rekursif ganda.
schily

6
@ Schily Di sisi lain, apa yang akan menjadi shell tanpa parser yang bagus.
Emmanuel

1
Masalahnya adalah Anda harus tahu di mana string berakhir sebelum Anda memanggil parser. Ini relatif sederhana dengan backticks, tetapi sulit dengan tanda kurung karena mereka digunakan untuk berbagai keperluan di shell. Jadi, Anda perlu pengurai dua kali dan dengan cara yang tidak ada di Bourne Shell.
schily
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.