Untuk bash saja , jawaban Kevin Little mengusulkan yang sederhana ${!#}. Uji dengan menggunakan bash -c 'echo ${!#}' arg1 arg2 arg3. Untuk bash , ksh dan zsh , jawaban Dennis Williamson mengusulkan ${@: -1}. Apalagi ${*: -1}bisa juga digunakan. Uji dengan menggunakan zsh -c 'echo ${*: -1}' arg1 arg2 arg3. Tapi itu tidak berhasil untuk dash , csh dan tcsh .
olibre
2
${!#}, tidak seperti ${@: -1}, juga berfungsi dengan ekspansi parameter. Anda dapat mengujinya dengan bash -c 'echo ${!#%.*}' arg1.out arg2.out arg3.out.
Arch Stanton
Jawaban:
177
Ini sedikit hack:
for last;do true;done
echo $last
Yang ini juga cukup portabel (sekali lagi, harus bekerja dengan bash, ksh dan sh) dan tidak menggeser argumen, yang bisa bagus.
Ia menggunakan fakta yang forsecara implisit memotong argumen jika Anda tidak memberi tahu apa yang harus diulang, dan fakta bahwa untuk variabel loop tidak dibatasi: mereka menyimpan nilai terakhir yang ditetapkan.
Dengan Solaris lama, dengan shell bourne lama (bukan POSIX), saya harus menulis "untuk yang terakhir di" $ @ "; lakukan benar; selesai"
mcoolive
8
@mcoolive @LaurenceGolsalves selain lebih portabel, for last in "$@"; do :; donejuga membuat maksudnya lebih jelas.
Adrian Günter
1
@ mcoolive: ia bahkan bekerja di shell bourne unix v7 dari tahun 1979. Anda tidak bisa mendapatkan lebih portabel jika berjalan di kedua v7 sh dan POSIX sh :)
Bagi mereka (seperti saya) yang bertanya-tanya mengapa ruang dibutuhkan, man bash mengatakan ini tentang itu:> Perhatikan bahwa offset negatif harus dipisahkan dari usus besar dengan setidaknya satu ruang untuk menghindari kebingungan dengan: - ekspansi.
foo
1
Saya telah menggunakan ini dan rusak di MSYS2 bash di windows saja. Aneh.
Steven Lu
2
Catatan: Jawaban ini berfungsi untuk semua array Bash, tidak seperti ${@:$#}yang hanya berfungsi $@. Jika Anda menyalin $@ke array baru dengan arr=("$@"), ${arr[@]:$#}tidak akan ditentukan. Ini karena $@memiliki elemen ke-0 yang tidak termasuk dalam "$@"ekspansi.
Tn. Llama
@ Mr.Llama: Tempat lain untuk menghindari $#adalah ketika mengulangi array karena, di Bash, array jarang dan sementara $#akan menunjukkan jumlah elemen dalam array itu tidak selalu menunjuk ke elemen terakhir (atau elemen +1). Dengan kata lain, seseorang seharusnya tidak melakukan for ((i = 0; i++; i < $#)); do something "${array[$i]}"; donedan sebaliknya melakukan for element in "${array[@]}"; do something "$element"; doneatau mengulangi indeks: for index in "${!array[@]}"; do something "$index" "${array[$index]}"; donejika Anda perlu melakukan sesuatu dengan nilai-nilai indeks.
Dijeda sampai pemberitahuan lebih lanjut.
80
$ set quick brown fox jumps
$ echo ${*:-1:1}# last argument
jumps
$ echo ${*:-1}# or simply
jumps
$ echo ${*:-2:1}# next to last
fox
Ruang tersebut diperlukan agar tidak bisa ditafsirkan sebagai nilai default .
$BASH_ARGVtidak berfungsi di dalam fungsi bash (kecuali saya melakukan sesuatu yang salah).
Big McLargeHuge
1
BASH_ARGV memiliki argumen ketika bash dipanggil (atau ke suatu fungsi) bukan daftar argumen posisi saat ini.
Isaac
Perhatikan juga apa yang BASH_ARGVakan menghasilkan Anda adalah nilai yang diberikan arg terakhir, alih-alih sekadar "nilai terakhir". Misalnya !: jika Anda memberikan satu argumen tunggal, maka Anda memanggil shift, tidak ${@:$#}akan menghasilkan apa-apa (karena Anda menggeser argumen satu-satunya!), Namun, BASH_ARGVmasih akan memberi Anda argumen terakhir (sebelumnya).
Steven Lu
30
Gunakan pengindeksan dikombinasikan dengan panjang:
Berikut ini akan bekerja untuk Anda. @ Adalah untuk berbagai argumen. : berarti pada. $ # adalah panjang dari array argumen. Jadi hasilnya adalah elemen terakhir:
${@:$#}
Contoh:
function afunction{
echo ${@:$#} }
afunction -d -o local50#Outputs 50
Sementara contohnya adalah untuk suatu fungsi, skrip juga bekerja dengan cara yang sama. Saya suka jawaban ini karena jelas dan ringkas.
Jonah Braun
1
Dan itu bukan hacky. Ini menggunakan fitur eksplisit bahasa, bukan efek samping atau qwerks khusus. Ini harus menjadi jawaban yang diterima.
musicin3d
25
Menemukan ini ketika mencari untuk memisahkan argumen terakhir dari semua argumen sebelumnya. Sementara beberapa jawaban mendapatkan argumen terakhir, mereka tidak banyak membantu jika Anda membutuhkan semua argumen lainnya juga. Ini bekerja lebih baik:
The Steven Penny jawabannya adalah sedikit lebih bagus: digunakan ${@: -1}untuk terakhir dan ${@: -2:1}untuk detik terakhir (dan seterusnya ...). Contoh: bash -c 'echo ${@: -1}' prog 0 1 2 3 4 5 6cetakan 6. Untuk tetap menggunakan pendekatan AgileZebra saat ini, gunakan ${@:$#-1:1}untuk mendapatkan yang kedua terakhir . Contoh: bash -c 'echo ${@:$#-1:1}' prog 0 1 2 3 4 5 6cetakan 5. (dan ${@:$#-2:1}untuk mendapatkan yang terakhir ketiga dan seterusnya ...)
olibre
4
Jawaban AgileZebra menyediakan cara untuk mendapatkan semua kecuali argumen terakhir sehingga saya tidak akan mengatakan jawaban Steven menggantikannya. Namun, sepertinya tidak ada alasan untuk menggunakan $((...))untuk mengurangi angka 1, Anda cukup menggunakan ${@:1:$# - 1}.
dkasak
Terima kasih dkasak. Diperbarui untuk mencerminkan penyederhanaan Anda.
AgileZebra
22
Ini bekerja di semua shell yang kompatibel dengan POSIX:
Lihat komentar ini terlampir pada jawaban identik yang lebih tua.
Dijeda sampai pemberitahuan lebih lanjut.
1
Solusi portabel paling sederhana yang saya lihat di sini. Yang ini tidak memiliki masalah keamanan, @DennisWilliamson, mengutip secara empiris tampaknya dilakukan dengan benar, kecuali ada cara untuk mengatur $#ke string sewenang-wenang (saya tidak berpikir begitu). eval last=\"\${$#}\"juga berfungsi dan jelas benar. Jangan melihat mengapa kutipan tidak diperlukan.
Palec
1
Untuk bash , zsh , dash dan ksheval last=\"\${$#}\" baik-baik saja. Tapi untuk csh dan tcsh digunakan eval set last=\"\${$#}\". Lihat contoh ini: tcsh -c 'eval set last=\"\${$#}\"; echo "$last"' arg1 arg2 arg3.
olibre
12
Inilah solusi tambang:
cukup portabel (semua POSIX sh, bash, ksh, zsh) harus berfungsi
Ini adalah ide yang bagus, tapi saya punya beberapa saran: Pertama mengutip harus ditambahkan di sekitar "$1"dan "$#"(lihat jawaban yang bagus ini unix.stackexchange.com/a/171347 ). Kedua, echosayangnya non-portabel (terutama untuk -n), jadi printf '%s\n' "$1"sebaiknya digunakan.
joki
terima kasih @joki Saya bekerja dengan banyak sistem unix yang berbeda dan saya juga tidak akan percaya echo -n, namun saya tidak mengetahui sistem posix mana pun yang echo "$1"akan gagal. Bagaimanapun, printfmemang lebih mudah ditebak - diperbarui.
Michał Šrajer
@ MichałŠrajer mempertimbangkan kasus di mana "$ 1" adalah "-n" atau "-", jadi misalnya ntharg 1 -natau ntharg 1 --dapat menghasilkan hasil yang berbeda di berbagai sistem. Kode yang Anda miliki sekarang aman!
joki
10
Dari solusi terlama hingga yang lebih baru:
Solusi paling portabel, bahkan lebih tua sh(bekerja dengan spasi dan karakter gumpal) (tanpa loop, lebih cepat):
eval printf "'%s\n'""\"\${$#}\""
Sejak versi 2.01 dari bash
$ set--The quick brown fox jumps over the lazy dog
$ printf '%s\n'"${!#} ${@:(-1)} ${@: -1} ${@:~0} ${!#}"
dog dog dog dog dog
Untuk ksh, zsh dan bash:
$ printf '%s\n'"${@: -1} ${@:~0}"# the space beetwen `:`# and `-1` is a must.
dog dog
Dan untuk "selanjutnya":
$ printf '%s\n'"${@:~1:1}"
lazy
Menggunakan printf untuk menyelesaikan masalah dengan argumen yang dimulai dengan tanda hubung (seperti -n ).
Untuk semua shell dan untuk yang lebih tua sh(bekerja dengan spasi dan karakter glob) adalah:
$ set--The quick brown fox jumps over the lazy dog "the * last argument"
$ eval printf "'%s\n'""\"\${$#}\""The last * argument
Atau, jika Anda ingin mengatur lastvar:
$ eval last=\${$#}; printf '%s\n' "$last"The last * argument
shift $(($# - 1))- tidak perlu untuk utilitas eksternal. Bekerja di Bash, ksh, zsh dan dash.
Dijeda sampai pemberitahuan lebih lanjut.
@ Dennis: Bagus! Saya tidak tahu tentang $((...))sintaks.
Laurence Gonsalves
Anda ingin menggunakan printf '%s\n' "$1"untuk menghindari perilaku yang tidak terduga dari echo(misalnya untuk -n).
joki
2
Jika Anda ingin melakukannya dengan cara yang tidak merusak, salah satu caranya adalah meneruskan semua argumen ke suatu fungsi dan mengembalikan yang terakhir:
#!/bin/bash
last(){if[[ $# -ne 0 ]] ; then
shift $(expr $# - 1)
echo "$1"#else#do something when no argumentsfi}
lastvar=$(last "$@")
echo $lastvar
echo "$@"
pax>./qq.sh 123 a b
b
123 a b
Jika Anda tidak peduli tentang mempertahankan argumen lain, Anda tidak memerlukannya dalam suatu fungsi tetapi saya kesulitan memikirkan situasi di mana Anda tidak akan pernah ingin menyimpan argumen lain kecuali mereka sudah diproses, dalam hal ini saya akan menggunakan proses / shift / proses / shift / ... metode pemrosesan secara berurutan.
Saya berasumsi di sini bahwa Anda ingin menyimpannya karena Anda belum mengikuti metode berurutan. Metode ini juga menangani kasus di mana tidak ada argumen, mengembalikan "". Anda dapat dengan mudah menyesuaikan perilaku itu dengan memasukkan elseklausul yang dikomentari .
Saya tahu Anda memposting ini selamanya, tetapi solusi ini hebat - senang ada yang diposting tcsh!
user3295674
2
Saya menemukan jawaban @ AgileZebra (ditambah komentar @ starfry) yang paling berguna, tetapi disetel headsmenjadi skalar. Array mungkin lebih berguna:
Saya sudah melakukannya dengan menambahkan tanda kurung, misalnya echo "${heads[-1]}"mencetak elemen terakhir di heads. Atau apakah saya melewatkan sesuatu?
eval untuk referensi tidak langsung adalah berlebihan, belum lagi praktik buruk, dan masalah keamanan besar (nilainya tidak mengutip dalam gema atau di luar $ (). Bash memiliki sintaks bawaan untuk referensi tidak langsung, untuk var apa pun: !Jadi last="${!#}"akan menggunakan hal yang sama pendekatan (referensi tidak langsung pada $ #) dengan cara yang jauh lebih aman, kompak, builtin, waras. Dan dikutip dengan benar
MestreLion
Lihat cara yang lebih bersih untuk melakukan hal yang sama di jawaban lain .
Palec
Kutipan @MestreLion tidak diperlukan pada RHS dari =.
Tom Hale
1
@ TomHale: benar untuk kasus tertentu ${!#}, tetapi tidak secara umum: kutipan masih diperlukan jika konten mengandung spasi putih literal, seperti last='two words'. Hanya ruang $()kosong yang aman terlepas dari konten.
MestreLion
1
Setelah membaca jawaban di atas saya menulis skrip shell Q & D (harus bekerja pada sh dan bash) untuk menjalankan g ++ di PGM.cpp untuk menghasilkan gambar PGM yang dapat dieksekusi. Ini mengasumsikan bahwa argumen terakhir pada baris perintah adalah nama file (.cpp adalah opsional) dan semua argumen lainnya adalah opsi.
#!/bin/shif[ $# -lt 1 ]then
echo "Usage: `basename $0` [opt] pgm runs g++ to compile pgm[.cpp] into pgm"
exit 2fi
OPT=
PGM=# PGM is the last argument, all others are considered optionsfor F;do OPT="$OPT $PGM"; PGM=$F;done
DIR=`dirname $PGM`
PGM=`basename $PGM .cpp`# put -o first so it can be overridden by -o specified in OPTset-x
g++-o $DIR/$PGM $OPT $DIR/$PGM.cpp
Sekarang saya hanya perlu menambahkan beberapa teks karena jawaban saya terlalu pendek untuk dikirim. Saya perlu menambahkan lebih banyak teks untuk diedit.
Pendekatan eval telah disajikan di sini berkali-kali, tetapi yang ini memiliki penjelasan tentang cara kerjanya. Bisa lebih ditingkatkan, tetapi tetap layak dipertahankan.
Saya menduga ini akan gagal dengan ./arguments.sh "nilai terakhir"
Thomas
Terima kasih telah memeriksa Thomas, saya telah mencoba melakukan skrip as seperti Anda yang didaftarkan # ./arguments.sh "nilai terakhir" Argumen Terakhir adalah: nilai berfungsi dengan baik sekarang. # ./arguments.sh "pemeriksaan nilai terakhir dengan dobel" Argumen Terakhir adalah: dobel
Ranjithkumar T
Masalahnya adalah bahwa argumen terakhir adalah 'nilai terakhir', dan bukan nilai. Kesalahan ini disebabkan oleh argumen yang berisi spasi.
Thomas
0
Ada cara yang jauh lebih ringkas untuk melakukan ini. Argumen untuk skrip bash dapat dibawa ke dalam array, yang membuat berurusan dengan elemen lebih sederhana. Skrip di bawah ini akan selalu mencetak argumen terakhir yang dilewatkan ke skrip.
argArray=("$@")# Add all script arguments to argArray
arrayLength=${#argArray[@]}# Get the length of the array
lastArg=$((arrayLength -1))# Arrays are zero based, so last arg is -1
echo ${argArray[$lastArg]}
Ini hanya berfungsi jika argumen terakhir tidak mengandung spasi.
Palec
Prelast Anda gagal jika argumen terakhir adalah kalimat yang dilampirkan dalam tanda kutip ganda, dengan kalimat tersebut seharusnya menjadi satu argumen.
Stephane
0
Untuk mengembalikan argumen terakhir dari perintah yang terakhir digunakan, gunakan parameter khusus:
$_
Dalam hal ini, ini akan berfungsi jika digunakan dalam skrip sebelum perintah lain dipanggil.
${!#}
. Uji dengan menggunakanbash -c 'echo ${!#}' arg1 arg2 arg3
. Untuk bash , ksh dan zsh , jawaban Dennis Williamson mengusulkan${@: -1}
. Apalagi${*: -1}
bisa juga digunakan. Uji dengan menggunakanzsh -c 'echo ${*: -1}' arg1 arg2 arg3
. Tapi itu tidak berhasil untuk dash , csh dan tcsh .${!#}
, tidak seperti${@: -1}
, juga berfungsi dengan ekspansi parameter. Anda dapat mengujinya denganbash -c 'echo ${!#%.*}' arg1.out arg2.out arg3.out
.Jawaban:
Ini sedikit hack:
Yang ini juga cukup portabel (sekali lagi, harus bekerja dengan bash, ksh dan sh) dan tidak menggeser argumen, yang bisa bagus.
Ia menggunakan fakta yang
for
secara implisit memotong argumen jika Anda tidak memberi tahu apa yang harus diulang, dan fakta bahwa untuk variabel loop tidak dibatasi: mereka menyimpan nilai terakhir yang ditetapkan.sumber
true
adalah bagian dari POSIX .for last in "$@"; do :; done
juga membuat maksudnya lebih jelas.Ini hanya untuk Bash:
sumber
${@:$#}
yang hanya berfungsi$@
. Jika Anda menyalin$@
ke array baru denganarr=("$@")
,${arr[@]:$#}
tidak akan ditentukan. Ini karena$@
memiliki elemen ke-0 yang tidak termasuk dalam"$@"
ekspansi.$#
adalah ketika mengulangi array karena, di Bash, array jarang dan sementara$#
akan menunjukkan jumlah elemen dalam array itu tidak selalu menunjuk ke elemen terakhir (atau elemen +1). Dengan kata lain, seseorang seharusnya tidak melakukanfor ((i = 0; i++; i < $#)); do something "${array[$i]}"; done
dan sebaliknya melakukanfor element in "${array[@]}"; do something "$element"; done
atau mengulangi indeks:for index in "${!array[@]}"; do something "$index" "${array[$index]}"; done
jika Anda perlu melakukan sesuatu dengan nilai-nilai indeks.Ruang tersebut diperlukan agar tidak bisa ditafsirkan sebagai nilai default .
Perhatikan bahwa ini hanya untuk bash.
sumber
${@: 1:$#-1}
echo ${@: -1} ${@: 1:$#-1}
Jawaban paling sederhana untuk bash 3.0 atau lebih tinggi adalah
Itu dia.
Output adalah:
sumber
$BASH_ARGV
tidak berfungsi di dalam fungsi bash (kecuali saya melakukan sesuatu yang salah).BASH_ARGV
akan menghasilkan Anda adalah nilai yang diberikan arg terakhir, alih-alih sekadar "nilai terakhir". Misalnya !: jika Anda memberikan satu argumen tunggal, maka Anda memanggil shift, tidak${@:$#}
akan menghasilkan apa-apa (karena Anda menggeser argumen satu-satunya!), Namun,BASH_ARGV
masih akan memberi Anda argumen terakhir (sebelumnya).Gunakan pengindeksan dikombinasikan dengan panjang:
Perhatikan bahwa ini hanya untuk bash.
sumber
echo ${@:$#}
Berikut ini akan bekerja untuk Anda. @ Adalah untuk berbagai argumen. : berarti pada. $ # adalah panjang dari array argumen. Jadi hasilnya adalah elemen terakhir:
Contoh:
Perhatikan bahwa ini hanya untuk bash.
sumber
Menemukan ini ketika mencari untuk memisahkan argumen terakhir dari semua argumen sebelumnya. Sementara beberapa jawaban mendapatkan argumen terakhir, mereka tidak banyak membantu jika Anda membutuhkan semua argumen lainnya juga. Ini bekerja lebih baik:
Perhatikan bahwa ini hanya untuk bash.
sumber
${@: -1}
untuk terakhir dan${@: -2:1}
untuk detik terakhir (dan seterusnya ...). Contoh:bash -c 'echo ${@: -1}' prog 0 1 2 3 4 5 6
cetakan6
. Untuk tetap menggunakan pendekatan AgileZebra saat ini, gunakan${@:$#-1:1}
untuk mendapatkan yang kedua terakhir . Contoh:bash -c 'echo ${@:$#-1:1}' prog 0 1 2 3 4 5 6
cetakan5
. (dan${@:$#-2:1}
untuk mendapatkan yang terakhir ketiga dan seterusnya ...)$((...))
untuk mengurangi angka 1, Anda cukup menggunakan${@:1:$# - 1}
.Ini bekerja di semua shell yang kompatibel dengan POSIX:
Sumber: http://www.faqs.org/faqs/unix-faq/faq/part2/section-12.html
sumber
$#
ke string sewenang-wenang (saya tidak berpikir begitu).eval last=\"\${$#}\"
juga berfungsi dan jelas benar. Jangan melihat mengapa kutipan tidak diperlukan.eval last=\"\${$#}\"
baik-baik saja. Tapi untuk csh dan tcsh digunakaneval set last=\"\${$#}\"
. Lihat contoh ini:tcsh -c 'eval set last=\"\${$#}\"; echo "$last"' arg1 arg2 arg3
.Inilah solusi tambang:
kejahataneval
Kode:
sumber
"$1"
dan"$#"
(lihat jawaban yang bagus ini unix.stackexchange.com/a/171347 ). Kedua,echo
sayangnya non-portabel (terutama untuk-n
), jadiprintf '%s\n' "$1"
sebaiknya digunakan.echo -n
, namun saya tidak mengetahui sistem posix mana pun yangecho "$1"
akan gagal. Bagaimanapun,printf
memang lebih mudah ditebak - diperbarui.ntharg 1 -n
atauntharg 1 --
dapat menghasilkan hasil yang berbeda di berbagai sistem. Kode yang Anda miliki sekarang aman!Dari solusi terlama hingga yang lebih baru:
Solusi paling portabel, bahkan lebih tua
sh
(bekerja dengan spasi dan karakter gumpal) (tanpa loop, lebih cepat):Sejak versi 2.01 dari bash
Untuk ksh, zsh dan bash:
Dan untuk "selanjutnya":
Menggunakan printf untuk menyelesaikan masalah dengan argumen yang dimulai dengan tanda hubung (seperti
-n
).Untuk semua shell dan untuk yang lebih tua
sh
(bekerja dengan spasi dan karakter glob) adalah:Atau, jika Anda ingin mengatur
last
var:Dan untuk "selanjutnya":
sumber
Jika Anda menggunakan Bash> = 3.0
sumber
echo ${BASH_ARGV[1]}
ARGV
singkatan dari "vector argumen."Sebab
bash
, komentar ini menyarankan yang sangat elegan:Sebagai bonus, ini juga berfungsi di
zsh
.sumber
Ini menggeser argumen dengan jumlah argumen minus 1, dan mengembalikan argumen pertama (dan hanya) yang tersisa, yang akan menjadi yang terakhir.
Saya hanya menguji dalam bash, tetapi harus bekerja di sh dan ksh juga.
sumber
shift $(($# - 1))
- tidak perlu untuk utilitas eksternal. Bekerja di Bash, ksh, zsh dan dash.$((...))
sintaks.printf '%s\n' "$1"
untuk menghindari perilaku yang tidak terduga dariecho
(misalnya untuk-n
).Jika Anda ingin melakukannya dengan cara yang tidak merusak, salah satu caranya adalah meneruskan semua argumen ke suatu fungsi dan mengembalikan yang terakhir:
Jika Anda tidak peduli tentang mempertahankan argumen lain, Anda tidak memerlukannya dalam suatu fungsi tetapi saya kesulitan memikirkan situasi di mana Anda tidak akan pernah ingin menyimpan argumen lain kecuali mereka sudah diproses, dalam hal ini saya akan menggunakan proses / shift / proses / shift / ... metode pemrosesan secara berurutan.
Saya berasumsi di sini bahwa Anda ingin menyimpannya karena Anda belum mengikuti metode berurutan. Metode ini juga menangani kasus di mana tidak ada argumen, mengembalikan "". Anda dapat dengan mudah menyesuaikan perilaku itu dengan memasukkan
else
klausul yang dikomentari .sumber
Untuk tcsh:
Saya cukup yakin ini akan menjadi solusi portabel, kecuali untuk penugasan.
sumber
Saya menemukan jawaban @ AgileZebra (ditambah komentar @ starfry) yang paling berguna, tetapi disetel
heads
menjadi skalar. Array mungkin lebih berguna:Perhatikan bahwa ini hanya untuk bash.
sumber
echo "${heads[-1]}"
mencetak elemen terakhir diheads
. Atau apakah saya melewatkan sesuatu?Solusi menggunakan
eval
:sumber
!
Jadilast="${!#}"
akan menggunakan hal yang sama pendekatan (referensi tidak langsung pada $ #) dengan cara yang jauh lebih aman, kompak, builtin, waras. Dan dikutip dengan benar=
.${!#}
, tetapi tidak secara umum: kutipan masih diperlukan jika konten mengandung spasi putih literal, sepertilast='two words'
. Hanya ruang$()
kosong yang aman terlepas dari konten.Setelah membaca jawaban di atas saya menulis skrip shell Q & D (harus bekerja pada sh dan bash) untuk menjalankan g ++ di PGM.cpp untuk menghasilkan gambar PGM yang dapat dieksekusi. Ini mengasumsikan bahwa argumen terakhir pada baris perintah adalah nama file (.cpp adalah opsional) dan semua argumen lainnya adalah opsi.
sumber
LAST
Argumen berikut akan diatur ke terakhir tanpa mengubah lingkungan saat ini:Jika argumen lain tidak lagi diperlukan dan dapat digeser, dapat disederhanakan menjadi:
Untuk alasan portabilitas berikut:
dapat diganti dengan:
Mengganti juga
$()
dengan backquotes yang kami dapatkan:sumber
Sekarang saya hanya perlu menambahkan beberapa teks karena jawaban saya terlalu pendek untuk dikirim. Saya perlu menambahkan lebih banyak teks untuk diedit.
sumber
$argv
tetapi tidak$#argv
-$argv[(count $argv)]
bekerja pada ikan).Ini adalah bagian dari fungsi salin saya:
Untuk digunakan dalam skrip, lakukan ini:
Penjelasan (paling bersarang terlebih dahulu):
$(echo '$'"$#")
mengembalikan di$[nr]
mana[nr]
jumlah parameter. Misalnya string$123
(tidak diperluas).echo $123
mengembalikan nilai parameter 123, ketika dievaluasi.eval
hanya memperluas$123
ke nilai parameter, mislast_arg
. Ini ditafsirkan sebagai string dan dikembalikan.Bekerja dengan Bash pada pertengahan 2015.
sumber
sumber
Coba skrip di bawah ini untuk menemukan argumen terakhir
Keluaran:
Terima kasih.
sumber
Ada cara yang jauh lebih ringkas untuk melakukan ini. Argumen untuk skrip bash dapat dibawa ke dalam array, yang membuat berurusan dengan elemen lebih sederhana. Skrip di bawah ini akan selalu mencetak argumen terakhir yang dilewatkan ke skrip.
Output sampel
sumber
Menggunakan ekspansi parameter (hapus awal yang cocok):
Juga mudah untuk mendapatkan semua sebelum yang terakhir:
sumber
Untuk mengembalikan argumen terakhir dari perintah yang terakhir digunakan, gunakan parameter khusus:
Dalam hal ini, ini akan berfungsi jika digunakan dalam skrip sebelum perintah lain dipanggil.
sumber
Gunakan saja
!$
.sumber