Saya dulu menggunakan CShell (csh), yang memungkinkan Anda membuat alias yang mengambil parameter. Notasi itu seperti sesuatu
alias junk="mv \\!* ~/.Trash"
Di Bash, ini sepertinya tidak berhasil. Mengingat bahwa Bash memiliki banyak fitur yang berguna, saya akan berasumsi bahwa yang ini telah diterapkan tetapi saya bertanya-tanya bagaimana caranya.
"$1"
ls
untukls -la
, kemudian mengetikls foo bar
akan benar-benar mengeksekusils -la foo bar
. Pada baris perintah"alias test_args="echo PREFIX --$1-- SUFFIX"
, yang ketika dipanggil dengantest_args ABCD
menghasilkan keluaran konsol berikutPREFIX ---- SUFFIX ABCD
Jawaban:
Bash alias tidak langsung menerima parameter. Anda harus membuat fungsi.
alias
tidak menerima parameter tetapi fungsi dapat dipanggil seperti alias. Sebagai contoh:Omong-omong, fungsi Bash yang ditentukan dalam
.bashrc
file Anda dan lainnya tersedia sebagai perintah di dalam shell Anda. Jadi misalnya Anda dapat memanggil fungsi sebelumnya seperti inisumber
$1
kutipan?source
ing .bashrc Anda akan menambahkan fungsi tersebut tetapi itu tidak akan menyamakan alias yang lama. Karena alias adalah preseden yang lebih tinggi daripada fungsi, alias akan mencoba menggunakan alias. Anda harus menutup dan membuka kembali shell Anda, atau panggilunalias <name>
. Mungkin saya akan menyelamatkan seseorang selama 5 menit yang saya sia-siakan.exec bash
: Ini akan memulai shell baru, memberi Anda bacaan bersih tentang konfigurasi Anda, sama seperti jika Anda menutup dan membuka kembali, tetapi menjaga pengaturan variabel lingkungan sesi itu juga . Juga, mengeksekusibash
tanpa eksekutif dapat berguna ketika Anda ingin menangani berpikir seperti tumpukan.mv "$1" "$1.bak"
. tanpa tanda kutip, jika $ 1 adalah "hello world", Anda akan mengeksekusimv hello world hello world.bak
bukanmv "hello world" "hello world.bak"
.Menyempurnakan jawaban di atas, Anda bisa mendapatkan sintaks 1 baris seperti yang Anda bisa untuk alias, yang lebih nyaman untuk definisi ad-hoc dalam file shell atau .bashrc:
Jangan lupa tanda titik koma sebelum tanda kurung tutup. Demikian pula, untuk pertanyaan aktual:
Atau:
sumber
mv "$1" "$1.bak"; cp "$2" "$1"
menjadimv "$1" "$1.bak" && cp "$2" "$1"
untuk tidak kehilangan data Anda ketikamv
mengalami masalah (misalnya, sistem file penuh).Pertanyaannya adalah salah. Anda tidak membuat alias yang mengambil parameter karena
alias
hanya menambahkan nama kedua untuk sesuatu yang sudah ada. Fungsionalitas yang diinginkan OP adalahfunction
perintah untuk membuat fungsi baru. Anda tidak perlu alias fungsi karena fungsi sudah memiliki nama.Saya pikir Anda menginginkan sesuatu seperti ini:
Itu dia! Anda dapat menggunakan parameter $ 1, $ 2, $ 3, dll, atau isi semuanya dengan $ @
sumber
echo -e '#!/bin/bash\nshopt -s expand_aliases\nalias asrc='\''echo "${BASH_SOURCE[0]}"'\'' # note the '\''s\nfunction fsrc(){ echo "${BASH_SOURCE[0]}";}'>>file2&&echo -e '#!/bin/bash\n. file2\nalias rl='\''readlink -f'\''\nrl $(asrc)\nrl $(fsrc)'>>file1&&chmod +x file1&&./file1;rm -f file1 file2
$@
untuk mendukung nama file dengan spasi, dll.TL; DR: Lakukan ini sebagai gantinya
Jauh lebih mudah dan lebih mudah dibaca untuk menggunakan fungsi daripada alias untuk meletakkan argumen di tengah-tengah perintah.
Jika Anda terus membaca, Anda akan mempelajari hal-hal yang tidak perlu Anda ketahui tentang pemrosesan argumen shell. Pengetahuan itu berbahaya. Dapatkan saja hasil yang Anda inginkan, sebelum sisi gelap selamanya mengendalikan nasib Anda.
Klarifikasi
bash
alias melakukan menerima argumen, tetapi hanya pada akhir :Menempatkan argumen ke tengah - tengah komando via
alias
memang mungkin tetapi itu menjadi jelek.Jangan coba ini di rumah, anak-anak!
Jika Anda suka menghindari batasan dan melakukan apa yang orang lain katakan tidak mungkin, inilah resepnya. Hanya saja, jangan salahkan saya jika rambut Anda menjadi kusut dan wajah Anda berakhir dengan jelaga-gaya ilmuwan gila.
Solusinya adalah meneruskan argumen yang
alias
hanya menerima di akhir ke pembungkus yang akan memasukkannya di tengah dan kemudian jalankan perintah Anda.Solusi 1
Jika Anda benar-benar menentang penggunaan fungsi, Anda dapat menggunakan:
Anda dapat mengganti
$@
dengan$1
jika Anda hanya menginginkan argumen pertama.Penjelasan 1
Ini menciptakan fungsi sementara
f
, yang meneruskan argumen (catatan yangf
disebut di bagian paling akhir). Theunset -f
menghilangkan definisi fungsi sebagai alias dijalankan sehingga tidak berkeliaran setelah itu.Solusi 2
Anda juga dapat menggunakan subkulit:
Penjelasan 2
Alias membangun perintah seperti:
Komentar:
Pengganti
_
diperlukan, tetapi bisa berupa apa saja. Ini akan diatur kesh
's$0
, dan diperlukan sehingga pertama dari argumen yang diberikan pengguna tidak bisa dikonsumsi. Demonstrasi:Kutipan tunggal di dalam tanda kutip tunggal diperlukan. Berikut ini contohnya yang tidak bekerja dengan tanda kutip ganda:
Di sini nilai-nilai shell interaktif
$0
dan$@
diganti menjadi dua kali dikutip sebelum diteruskansh
. Inilah buktinya:Kutipan tunggal memastikan bahwa variabel-variabel ini tidak ditafsirkan oleh shell interaktif, dan diteruskan secara harfiah
sh -c
.Anda dapat menggunakan tanda kutip ganda dan
\$@
, tetapi praktik terbaik adalah mengutip argumen Anda (karena mungkin mengandung spasi), dan\"\$@\"
terlihat lebih jelek, tetapi dapat membantu Anda memenangkan kontes kebingungan di mana rambut yang kusut adalah prasyarat untuk masuk.sumber
alias gc='git checkout'
$@
? Mereka diperlukan jika Anda memiliki, misalnya, file dengan spasi di dalamnya.Solusi alternatif adalah dengan menggunakan marker , alat yang saya buat baru-baru ini yang memungkinkan Anda untuk "mem-bookmark" templat perintah dan dengan mudah menempatkan kursor pada penampung perintah:
Saya menemukan bahwa sebagian besar waktu, saya menggunakan fungsi shell jadi saya tidak perlu menulis perintah yang sering digunakan lagi dan lagi di baris perintah. Masalah menggunakan fungsi untuk use case ini, adalah menambahkan istilah baru ke kosakata perintah saya dan harus mengingat parameter fungsi apa yang merujuk pada perintah-nyata. Tujuan penanda adalah untuk menghilangkan beban mental itu.
sumber
Yang harus Anda lakukan adalah membuat fungsi di dalam alias:
Anda harus menempatkan tanda kutip ganda sekitar "$ 1" karena tanda kutip tunggal tidak akan berfungsi.
sumber
bash: syntax error near unexpected token '{mkdir'
.;
di dalam fungsi yang_mkcd
kemungkinan besar merupakan kesalahan dari situ.{
dan}
Berikut adalah tiga contoh fungsi yang saya miliki di saya
~/.bashrc
, yang pada dasarnya alias yang menerima parameter:.
.
.
Referensi:
sumber
Bash alias benar-benar menerima parameter. Saya baru saja menambahkan alias untuk membuat aplikasi reaksi baru yang menerima nama aplikasi sebagai parameter. Inilah proses saya:
Buka bash_profile untuk mengedit di nano
Tambahkan alias Anda, satu per baris:
Simpan dan keluar dari editor nano
Katakan terminal untuk menggunakan alias baru di .bash_profile
Itu dia! Anda sekarang dapat menggunakan alias baru Anda
sumber
NB: Jika idenya tidak jelas, itu ide yang buruk untuk menggunakan alias untuk apa pun kecuali alias, yang pertama adalah 'fungsi dalam alias' dan yang kedua adalah 'sulit dibaca redirect / sumber'. Juga, ada kekurangan (yang saya pikir akan menjadi jelas, tetapi kalau-kalau Anda bingung: Saya tidak bermaksud mereka benar-benar digunakan ... di mana saja!)
.................................................. .................................................. ............................................
Saya sudah menjawab ini sebelumnya, dan selalu seperti ini di masa lalu:
yang bagus dan bagus, kecuali Anda menghindari penggunaan semua fungsi secara bersamaan. dalam hal ini Anda dapat memanfaatkan kemampuan luas bash untuk mengarahkan ulang teks:
Keduanya memiliki panjang yang sama memberi atau mengambil beberapa karakter.
The nyata kicker adalah perbedaan waktu, bagian atas menjadi 'metode fungsi dan bagian bawah menjadi metode 'redirect-sumber'. Untuk membuktikan teori ini, waktunya berbicara untuk dirinya sendiri:
Ini adalah bagian bawah dari sekitar 200 hasil, yang dilakukan secara berkala. Tampaknya pembuatan / penghancuran fungsi membutuhkan lebih banyak waktu daripada pengalihan. Semoga ini akan membantu pengunjung masa depan untuk pertanyaan ini (tidak ingin menyimpannya untuk saya sendiri).
sumber
Jika Anda mencari cara umum untuk menerapkan semua params ke suatu fungsi, bukan hanya satu atau dua atau beberapa jumlah hardcode lainnya, Anda dapat melakukannya dengan cara ini:
Jadi pada contoh di atas, saya meneruskan semua parameter dari saat saya menjalankan
runjar
alias.Sebagai contoh, jika saya melakukannya
runjar hi there
akan benar-benar berjalanjava -jar myjar.jar hi there
. Jika saya melakukannyarunjar one two three
akan berjalanjava -jar myjar.jar one two three
.Saya suka
$@
solusi berbasis ini karena ia bekerja dengan sejumlah params.sumber
runjar
alih-alih menjadikannya sebagai alias ke fungsi? Tampaknya tidak perlu rumit!alias
-ed (atau memiliki sifat hal diteruskanalias
) dalam file bash? jika ya, maka saya tidak tahualias runjar='java -jar myjar.jar'
. Alias menerima argumen, tetapi hanya di akhir.Dengan hormat kepada semua yang mengatakan Anda tidak dapat memasukkan parameter di tengah alias saya baru saja mengujinya dan ternyata itu berhasil.
alias mycommand = "python3" $ 1 "script.py --folderoutput HASIL /"
ketika saya menjalankan perintah foobar saya, perintah itu bekerja persis seperti jika saya mengetik perintah itu dengan tangan.
sumber
alias myalias="echo 1 "$1" 3"; myalias 2
beri saya:1 3 2
Ada alasan teknis yang sah untuk menginginkan solusi umum untuk masalah bash alias tidak memiliki mekanisme untuk mengambil reposisi argumen sewenang-wenang. Salah satu alasannya adalah jika perintah yang ingin Anda jalankan akan terpengaruh oleh perubahan lingkungan yang dihasilkan dari menjalankan fungsi. Dalam semua kasus lain , fungsi harus digunakan.
Apa yang baru-baru ini memaksa saya untuk mencoba solusi untuk ini adalah bahwa saya ingin membuat beberapa perintah singkat untuk mencetak definisi variabel dan fungsi. Jadi saya menulis beberapa fungsi untuk tujuan itu. Namun, ada variabel tertentu yang (atau mungkin) diubah oleh pemanggilan fungsi itu sendiri. Diantaranya adalah:
FUNCNAME BASH_SOURCE BASH_LINENO BASH_ARGC BASH_ARGV
Perintah dasar yang saya gunakan (dalam suatu fungsi) untuk mencetak variabel defns. dalam bentuk output oleh perintah set adalah:
Misalnya:
Masalah: Ini tidak akan mencetak definisi variabel yang disebutkan di atas karena mereka berada dalam konteks saat ini , misalnya, jika dalam prompt shell interaktif (atau tidak dalam panggilan fungsi apa pun), FUNCNAME tidak didefinisikan. Tetapi fungsi saya memberi tahu saya informasi yang salah:
Salah satu solusi yang saya temukan telah disebutkan oleh orang lain di posting lain tentang topik ini. Untuk perintah khusus ini untuk mencetak variabel, dan yang hanya membutuhkan satu argumen, saya melakukan ini:
Yang memberikan output yang benar (tidak ada), dan status hasil (salah):
Namun, saya masih merasa harus menemukan solusi yang berfungsi untuk sejumlah argumen yang berubah-ubah.
Solusi Umum Untuk Melewati Argumen Sewenang-wenang Pada Perintah Bash Alias:
Misalnya:
Satu hal yang menyenangkan tentang solusi ini adalah bahwa semua trik khusus yang digunakan untuk menangani parameter posisi (argumen) untuk perintah akan bekerja ketika menyusun perintah yang terperangkap. Satu-satunya perbedaan adalah sintaks array harus digunakan.
Misalnya,
Jika Anda ingin "$ @", gunakan "$ {CMD_ARGV [@]}".
Jika Anda ingin "$ #", gunakan "$ {# CMD_ARGV [@]}".
Dll
sumber
Setelah saya melakukan beberapa proyek yang menyenangkan dan saya masih menggunakannya. Ini menunjukkan beberapa animasi sementara saya menyalin file melalui
cp
perintah karenacp
tidak menunjukkan apa-apa dan itu agak frustasi. Jadi saya membuat alias iniDan ini adalah skrip spiner
Terlihat seperti ini
Animasi bersepeda)
sumber
Untuk mengambil parameter, Anda harus menggunakan fungsi!
Namun $ @ diinterpretasikan ketika membuat alias alih-alih selama eksekusi alias dan melarikan diri $ juga tidak berfungsi. Bagaimana saya mengatasi masalah ini?
Anda perlu menggunakan fungsi shell alih-alih alias untuk menyingkirkan masalah ini. Anda dapat mendefinisikan foo sebagai berikut:
ATAU
Terakhir, panggil foo Anda () menggunakan sintaks berikut:
Pastikan Anda menambahkan foo () ke
~/.bash_profile
atau~/.zshrc
file Anda.Dalam kasus Anda, ini akan berhasil
sumber
Fungsinya memang hampir selalu merupakan jawaban karena sudah banyak dikontribusikan dan dikonfirmasi oleh kutipan dari halaman manual ini: "Untuk hampir setiap tujuan, alias digantikan oleh fungsi shell."
Untuk kelengkapan dan karena ini dapat berguna (sintaksis sedikit lebih ringan) dapat dicatat bahwa ketika parameter mengikuti alias, mereka masih dapat digunakan (meskipun ini tidak akan memenuhi persyaratan OP). Ini mungkin yang paling mudah ditunjukkan dengan contoh:
memungkinkan saya untuk mengetik seperti
ssh_disc myhost
, yang akan diperluas seperti yang diharapkan:ssh -O stop myhost
Ini bisa berguna untuk perintah yang membutuhkan argumen kompleks (ingatan saya tidak seperti apa lagi ...)
sumber
Baik fungsi dan alias dapat menggunakan parameter seperti yang telah ditunjukkan di sini. Selain itu, saya ingin menunjukkan beberapa aspek lain:
1. fungsi berjalan dalam ruang lingkupnya sendiri, alias ruang lingkup saham
Mungkin berguna untuk mengetahui perbedaan ini jika Anda perlu menyembunyikan atau mengekspos sesuatu. Ini juga menunjukkan bahwa fungsi adalah pilihan yang lebih baik untuk enkapsulasi.
Keluaran:
2. skrip wrapper adalah pilihan yang lebih baik
Telah terjadi pada saya beberapa kali bahwa alias atau fungsi tidak dapat ditemukan ketika masuk melalui
ssh
atau melibatkan beralih nama pengguna atau lingkungan multi-pengguna. Ada tips dan trik dengan sumber file dot, atau yang menarik ini dengan alias:alias sd='sudo '
memungkinkan alias berikutnya inialias install='sd apt-get install'
berfungsi seperti yang diharapkan (perhatikan ruang tambahan disd='sudo '
). Namun, skrip wrapper berfungsi lebih baik daripada fungsi atau alias dalam kasus seperti ini. Keuntungan utama dengan skrip wrapper adalah skrip ini dapat dilihat / dieksekusi untuk di bawah jalur yang dimaksudkan (yaitu / usr / loca / bin /) di mana sebagai fungsi / alias perlu bersumber sebelum dapat digunakan. Misalnya, Anda meletakkan fungsi dalam ~ / .bash_profile atau ~ / .bashrc untukbash
, tetapi kemudian beralih ke shell lain (yaituzsh
) maka fungsinya tidak terlihat lagi. Jadi, ketika Anda ragu, skrip wrapper selalu merupakan solusi yang paling andal dan portabel.sumber
source
dalam suatu fungsi berfungsi dengan baik.f () { source /tmp/nst; }
tidak persis apa yang saya harapkan. Mungkin AndaPATH
salah sehingga menjalankan yang salahactivate
atau sesuatu; tetapi larisource
dari suatu fungsi berfungsi dengan baik.function
kata kunci dalam definisi Anda, lihat wiki.bash-hackers.org/scripting/obsolete -function funcname {
adalah sintaks ksh kuno dukungan bash untuk kompatibilitas mundur dengan kulit pra-POSIX, sedangkanfuncname() {
sintaksis resmi POSIX-standar.function funcname() {
adalah mismash dari keduanya yang tidak kompatibel dengan ksh kuno atau kompatibel dengan POSIX sh, dan yang dengan demikian sebaiknya dihindari.Inilah contohnya:
Sangat penting:
{
dan sebelumnya}
.;
setelah setiap perintah secara berurutan. Jika Anda lupa ini setelah perintah terakhir, Anda akan melihat>
prompt sebagai gantinya!"$1"
sumber
Seperti yang telah ditunjukkan oleh orang lain, menggunakan fungsi harus dianggap praktik terbaik.
Namun, berikut adalah pendekatan lain, meningkatkan
xargs
:Perhatikan bahwa ini memiliki efek samping sehubungan dengan pengalihan aliran.
sumber
Anda tidak perlu melakukan apa-apa, alias melakukan ini secara otomatis.
Sebagai contoh, jika saya ingin membuat git pull asal parameter, saya bisa membuat alias sebagai berikut:
dan ketika benar-benar memanggilnya, Anda dapat mengirimkan 'master' (nama cabang) sebagai parameter, seperti ini:
sumber