Saya memiliki skrip dalam file bernama instance:
echo "hello world"
echo ${1}
Dan ketika saya menjalankan skrip ini menggunakan:
./instance solfish
Saya mendapatkan hasil ini:
hello world
solfish
Tapi ketika saya lari:
echo $#
Dikatakan "0". Mengapa? Saya tidak mengerti apa $#
artinya.
Tolong jelaskan itu.
$#
? Apa yang ingin Anda capai? Di mana Anda mendapatkan perintah ini. Itu tidak relevan sama sekali.echo $#
dan kembali0
yang normal. Anda terkejut dengan ini, tetapi Anda tidak menjelaskan apa yang Anda harapkan atau mengapa Anda terkejut. Jadi itu akan membantu kami memberikan jawaban yang lebih baik jika Anda menjelaskan apa yang Anda harapkan. Apa yang Anda pikirecho $#
akan dilakukan. Jika Anda berlari./instance solfish
dan./instance
memuatecho $#
, itu akan mencetak1
dan tidak0
.Jawaban:
$#
adalah variabel khusus dalambash
, yang memperluas ke jumlah argumen (parameter posisi) yaitu$1, $2 ...
diteruskan ke skrip yang bersangkutan atau shell dalam kasus argumen langsung diteruskan ke shell misalnya dibash -c '...' ....
.Ini mirip dengan
argc
di C.Mungkin ini akan memperjelas:
Perhatikan bahwa,
bash -c
ambil argumen setelah perintah yang mengikutinya mulai dari 0 ($0
; secara teknis, itu hanyabash
cara untuk membiarkan Anda menetapkan$0
, bukan argumen sebenarnya), jadi_
digunakan di sini hanya sebagai pengganti; argumen aktual adalahx
($1
),y
($2
), danz
($3
).Demikian pula, dalam skrip Anda (dengan asumsi
script.sh
) jika Anda memiliki:Lalu ketika Anda melakukannya:
skrip akan menampilkan 2; juga,
akan menampilkan 1.
sumber
bash -c
, perilaku berbeda dari jika Anda menjalankan skrip shell yang dapat dieksekusi, karena dalam kasus terakhir argumen dengan indeks 0 adalah perintah shell yang digunakan untuk menjalankannya. Karena itu, saya pikir cara untuk memperbaiki jawaban ini adalah dengan mengubahnya untuk mengeksekusi skrip sebagai file daripada menggunakanbash -c
, karena itulah bagaimana penanya melakukannya.$0
akan menjadi skrip itu sendiri; argumen akan menjadi$1, $2, $3...
.bash -c
perilaku berbeda karena ini dimaksudkan untuk penggunaan non-interaktif dan argumen mengikuti perintah akan mulai dari$0
, saya telah menyebutkan ini dengan jelas saya percaya.bash -c
, Anda harus memberikanbash
beberapa nama yang bermakna sebagai pengisi untuk arg ke-0.bash -c 'echo "$@"' foo bar
hanya cetakbar
, karena"$@"
tidak termasuk$0
, sama seperti biasanya.bash -c
tidak "membuat $ 0 salah satu args", itu hanya memungkinkan Anda untuk set "$ 0" dengan cara yang sama Anda ketika menjalankan program dengan paraexecve
system call atau cara cangkang menimpa arg 0.$0
tidak boleh dianggap "salah satu argumen".echo $#
menampilkan jumlah parameter posisi skrip Anda.Anda tidak memilikinya, sehingga menghasilkan 0.
echo $#
berguna di dalam skrip, bukan sebagai perintah terpisah.Jika Anda menjalankan skrip dengan beberapa parameter seperti
yang
echo $#
ditempatkan ke dalam skrip akan menampilkan 2.sumber
echo $#
ke skrip Anda dan kemudian jalankan lagi./instance solfish
Anda harus mendapatkan jalur output tambahan1
karena Anda memberikan 1 parameter$#
biasanya digunakan dalam skrip bash untuk memastikan parameter dilewatkan. Umumnya Anda memeriksa parameter di awal skrip Anda.Misalnya, inilah cuplikan skrip yang saya kerjakan hari ini:
Untuk meringkas
$#
laporan, jumlah parameter diteruskan ke skrip. Dalam kasus Anda, Anda tidak melewati parameter dan hasil yang dilaporkan adalah0
.#
Kegunaan lain di BashIni
#
sering digunakan dalam bash untuk menghitung jumlah kemunculan atau panjang variabel.Untuk menemukan panjang string:
pengembalian:
11
Untuk menemukan jumlah elemen array:
pengembalian:
3
Untuk menemukan panjang elemen array pertama:
mengembalikan:
1
(PanjangA
, 0 adalah elemen pertama karena array menggunakan indeks / subskripsi berbasis nol).sumber
$# -ne 1
? Kenapa tidak$# -le 0
atau setara?$#
adalah jumlah argumen, tetapi ingat itu akan berbeda dalam suatu fungsi.$#
adalah jumlah parameter posisi yang diteruskan ke fungsi skrip, shell, atau shell . Ini karena, saat fungsi shell sedang berjalan, parameter posisi sementara diganti dengan argumen ke fungsi . Ini memungkinkan fungsi menerima dan menggunakan parameter posisinya sendiri.Skrip ini selalu dicetak
3
, terlepas dari berapa banyak argumen yang diteruskan ke skrip itu sendiri, karena"$#"
dalam fungsinyaf
memperluas ke jumlah argumen yang diteruskan ke fungsi:Ini penting karena ini berarti kode seperti ini tidak berfungsi seperti yang Anda harapkan, jika Anda tidak terbiasa dengan cara parameter posisi bekerja dalam fungsi shell:
Dalam
check_args
,$#
memperluas ke jumlah argumen yang diteruskan ke fungsi itu sendiri, yang dalam skrip itu selalu 0.Jika Anda ingin fungsi seperti itu dalam fungsi shell, Anda harus menulis sesuatu seperti ini sebagai gantinya:
Ini bekerja karena
$#
diperluas di luar fungsi dan dilewatkan ke fungsi sebagai salah satu yang parameter posisi. Di dalam fungsi,$1
memperluas ke parameter posisi pertama yang dilewatkan ke fungsi shell, bukan ke skrip bagian itu.Dengan demikian, seperti
$#
, parameter khusus$1
,$2
, dll, serta$@
dan$*
, juga berkaitan dengan argumen dilewatkan ke fungsi, ketika mereka diperluas dalam fungsi. Namun,$0
tidak tidak berubah nama fungsi, itulah sebabnya saya masih bisa menggunakannya untuk menghasilkan pesan kesalahan kualitas.Demikian pula, jika Anda mendefinisikan satu fungsi di dalam yang lain, Anda bekerja dengan parameter posisi yang diteruskan ke fungsi terdalam di mana ekspansi dilakukan:
Saya menelepon skrip ini
nested
dan (setelah menjalankanchmod +x nested
) saya menjalankannya:Ya saya tahu. "1 argumen" adalah bug pluralisasi.
Parameter posisi juga dapat diubah.
Jika Anda menulis skrip, parameter posisi di luar fungsi akan menjadi argumen baris perintah yang diteruskan ke skrip kecuali Anda telah mengubahnya .
Salah satu cara umum untuk mengubahnya adalah dengan
shift
builtin, yang menggeser setiap parameter posisi ke kiri oleh satu, menjatuhkan yang pertama dan menurun$#
1:Mereka juga dapat diubah dengan
set
builtin:sumber