Apa artinya di shell ketika kita meletakkan perintah di dalam tanda dolar dan tanda kurung: $ (perintah)


110

Saya hanya ingin memahami baris kode berikut di shell. Ini digunakan untuk mendapatkan direktori kerja saat ini. Saya sadar bahwa $(variable)nama mengembalikan nilai di dalam nama variabel, tetapi apa yang $(command)seharusnya dikembalikan? Apakah itu mengembalikan nilai setelah menjalankan perintah? Dalam hal ini, kita dapat menggunakan `untuk menjalankan perintah.

CWD="$(cd "$(dirname $0)"; pwd)"

Output yang sama dapat diambil dari baris kode berikut juga di versi shell yang berbeda

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Saya tidak dapat memahami arti dari $(cd..dan $(dirname.

Adakah yang bisa membantu saya untuk mengetahui bagaimana perintah ini dijalankan?


1
Dan inilah pertanyaan tentang keuntungan / kerugian dari $()vs ``.: stackoverflow.com/questions/9449778/…
Tidak ada

Jawaban:


115

Penggunaan $sejenisnya ${HOME}memberikan nilai HOME. Penggunaan cara $serupa $(echo foo)menjalankan apa pun yang ada di dalam tanda kurung di subkulit dan mengembalikannya sebagai nilainya. Dalam contoh saya, Anda akan mendapatkan fookarena echoakan menulis fooke standar


37
Iya; $(...)adalah cara yang lebih baik untuk menulis perintah daripada mencoba menggunakan tanda kutip belakang. Pertimbangkan untuk menulis: gcclib=$(dirname $(dirname $(which gcc)))/libmenggunakan tanda kutip belakang. Bahkan sebelum Anda mengalami kesulitan melakukannya di penurunan harga, itu lebih sulit karena Anda harus menghindari kutipan balik dari perintah bersarang, sedangkan Anda tidak dengan $(...)notasi.
Jonathan Leffler

7
Secara teknis, $(echo foo)membuat substitusi perintah, bukan subkulit. Jawaban lain saat ini benar. Saya pikir substitusi perintah dijalankan dalam subkulit, semacam itu, tetapi konsepnya masih berbeda.
trisis

4
@trysis - penggantian perintah pasti berjalan di subkulit , jadi perlu diperhatikan.
Eliran Malka

2
Saya memahami bahwa backtick menghasilkan hasil yang sama dengan $ (), tetapi apakah perbedaannya murni kosmetik? adakah alasan untuk menggunakan salah satu dari yang lain, selain itu $ () lebih terbaca?
Mitchell Tracy

2
"Penggunaan $ like $ (echo foo) berarti menjalankan apa pun yang ada di dalam tanda kurung di subkulit dan mengembalikannya sebagai nilainya." ... Ini membingungkan, karena perintah ini $(echo foo)akan mencoba menjalankan apa yang dikembalikan dari tanda kurung, perintah ini akan berjalan terlebih dahulu echo fookemudian akan mencoba menjalankan fooyang memberikan kesalahan
Akuntan م

21
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Adakah yang bisa membantu saya untuk mengetahui bagaimana perintah ini dijalankan?

Mari kita lihat bagian-bagian perintah yang berbeda. BASH_SOURCEadalah variabel bash array yang berisi nama file sumber. Jadi "${BASH_SOURCE[0]}"akan mengembalikan Anda nama file skrip.

dirnameadalah utilitas yang disediakan oleh coreutils GNU yang menghapus komponen terakhir dari nama file. Jadi jika Anda mengeksekusi skrip Anda dengan mengatakan bash foo, "$( dirname "${BASH_SOURCE[0]}" )"akan kembali .. Jika Anda berkata bash ../foo, itu akan kembali ..; karena bash /some/path/fooitu akan kembali /some/path.

Akhirnya, seluruh perintah "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"mendapatkan direktori absolut yang berisi skrip yang sedang dipanggil.

$(...) memungkinkan substitusi perintah, yaitu memungkinkan keluaran dari suatu perintah untuk menggantikan perintah itu sendiri dan dapat disarangkan.


1
Maaf karena terlambat 3 tahun ke pesta, tetapi bisakah Anda menjelaskan mengapa pernyataan itu berhasil? Anda mengatakan dirnamemengembalikan jalur file yang dieksekusi (relatif atau absolut ke direktori kerja saat ini), cdmengubah pwd ke direktori itu, dan pwdmencetak jalur absolut dari direktori kerja saat ini. Tapi kenapa mereka bergabung &&? Dan apa yang akan DIRterjadi jika cdgagal?
Christian

2
@Christian, &&mencegah pwdberjalan jika cdgagal, seperti itu DIRakan kosong daripada memiliki direktori yang salah.
Charles Duffy
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.