Apa yang dilakukan $ {0% / *} dalam skrip shell?

17

Maaf jika ini pertanyaan bodoh, tapi saya mencarinya tanpa hasil.

Apa sebenarnya yang dilakukan baris kedua?:

#!/bin/sh
cd ${0%/*} || exit 1

Saya tahu yang pertama adalah shebang, yang kedua mencoba untuk mengubah direktori tetapi bagian yang membingungkan adalah ${0%/*}.

Bisakah Anda jelaskan kepada saya bahwa baris kedua?

Navaro
sumber
2
Seperti yang dijelaskan oleh Andrea dalam sebuah jawaban, $ {0% / *} diterjemahkan ke jalur direktori yang diawali dengan nama skrip saat menjalankannya. Alternatifnya adalah dengan menggunakan dirnameperintah $(dirname $0)
bawaan
@alwayslearning: Versi shell dan shell apa yang Anda gunakan yang dirnameada di dalamnya ? Jelas bukan di Bash v4.3.11 yang merupakan shell default di Ubuntu Trusty.
David Foerster
Saya minta maaf atas kebingungan, hanya memeriksa bahwa dirnameitu bukan shell built-in.
belajar

Jawaban:

27

${0}adalah argumen pertama dari skrip, yaitu nama skrip atau path. Jika Anda memulai script seperti path/to/script.sh, maka ${0}akan persis string yang: path/to/script.sh.

Bagian %/*memodifikasi nilai ${0}. Artinya: ambil semua karakter hingga /diikuti dengan nama file. Pada contoh di atas, ${0%/*}akan path/to.

Anda dapat melihatnya beraksi di shell Anda:

$ x=path/to/script.sh
$ echo "${x%/*}"
path/to

Sh mendukung banyak jenis "substitusi parameter" lainnya. Inilah, misalnya, cara mengambil nama file alih-alih path:

$ echo "${x##*/}"
script.sh

Secara umum, %dan %%strip sufiks, sementara #dan ##strip awalan. Anda dapat membaca lebih lanjut tentang substitusi parameter .

Andrea Corbellini
sumber
2
"|| exit 1" ini tampaknya tidak perlu: jika tidak akan berubah dir $? sama dengan 1.
Josef Klimuk
2
Akan lebih baik untuk menyebutkan konstruksi didokumentasikan sebagai "Hapus awalan yang cocok / pola sufiks" dalam manual. Juga cara yang bagus untuk mengingat yang mana # adalah shift 3 ( kiri $),% adalah shift 5 ( kanan $), setidaknya pada keyboard AS.
chexum
1
@ JosefKlimuk: || exit 1 mungkin diperlukan karena cdmungkin keluar dengan status 2, bukan 1, karena kesalahan. Namun saya setuju bahwa itu tidak terlalu berguna (biasanya program tidak peduli dengan status keluar tertentu). Mungkin ini bagian dari skrip yang lebih besar?
Andrea Corbellini
1
@AndreaCorbellini Tentunya benar. Cukup banyak satu-satunya cara yang dapat digunakan sama sekali adalah sebagai bagian dari skrip yang lebih besar. Sebuah skrip yang baru saja mengubah direktori saat ini tidak memiliki efek, karena itu hanya mempengaruhi shell menjalankan skrip yang satu itu. Proses induk tidak pernah melihatnya.
hvd