Saya memiliki satu alias
set untuk rm
perintah saya . Jika saya menjalankan alias
perintah, inilah yang saya dapatkan sebagai output.
alias rm='rm -i'
Sekarang, ketika saya menjalankan rm
perintah itu berfungsi dengan baik seperti yang diharapkan.
rm ramesh
rm: remove regular empty file `ramesh'? y
Sekarang, saya sedang belajar tentang pemanggilan sistem yang dipanggil ketika saya menjalankan perintah. Untuk itu saya harus tahu tentang strace
perintah dari sini yang mencantumkan saya file yang dipanggil ketika saya menjalankan beberapa perintah. Perintahnya seperti di bawah ini.
strace -ff -e trace=file rm ramesh 2>&1
Perintah berfungsi dengan baik kecuali bahwa itu mengabaikan alias saya yang ada di tempat untuk rm
perintah saya . Menghapus file tanpa meminta pengguna.
Jadi, apakah strace
abaikan alias seperti ini? Jika demikian mengapa demikian?
EDIT:
Tidak yakin, apakah ini ada hubungannya tetapi type -a rm
memberi saya output sebagai,
rm is aliased to `rm -i'
rm is /bin/rm
Jadi apakah itu mempertimbangkan /bin/rm
dalam kasus ini yang mengapa pengguna tidak diminta sebelum dihapus?
strace
tidak mengabaikan alias, karena itu akan menyiratkan ada sesuatu yang diabaikan pada awalnya. Alias adalah fitur shell.strace
adalah program yang berbeda, dan distrace
dalam konsep alias tidak ada, maka tidak ada yang perlu diabaikan. API yang disediakan oleh kernel untuk menjalankan program tidak memiliki konsep alias juga, jadi tidak ada cara shell dapat memberitahu strace tentang alias, bahkan jika itu mau.strace
alias, Anda harus kestrace
shell, yang mengimplementasikan alias. Ada beberapa pendekatan yang dapat Anda ambil untuk melakukan itu:strace -p $$ &
ataustrace bash
ataustrace sh -c 'rm ramesh'
(yang terakhir juga akan mengabaikan alias, tetapi untuk alasan yang sama sekali berbeda.)Jawaban:
strace
tidak berjalanrm -i
karena alasan yang sama dengan:tidak menghasilkan
rm -i
.Alias adalah fitur dari beberapa shell untuk memungkinkan beberapa string secara otomatis diganti dengan yang lain ketika ditemukan dalam posisi perintah.
Di:
Kerang memperluas itu ke:
dan yang mengalami putaran interpretasi lain, dalam hal itu mengarah pada melaksanakan
whatever
perintah.alias hanya diperluas ketika ditemukan di posisi perintah (sebagai kata pertama dari baris perintah).
zsh
mendukung alias global .Anda bisa melakukannya:
Tetapi Anda tidak akan mau, karena itu berarti:
akan menampilkan
rm -i
misalnya.sumber
strace
menggunakanPATH
variabel lingkungan untuk menemukan program yang akan dilacak, daripada mengeksekusi melalui shell (yang akan mengacaukan output). Shell alias bukan program, ini fitur shell, jadistrace
abaikan saja.Berlari
strace strace rm
agak mencerahkan, juga menarik secara rekursif.sumber
Alias adalah fitur dari shell Anda. Namun, strace mengeksekusi perintah secara langsung (menggunakan
execve
, mungkin), yang tidak melibatkan shell. (Jika strace mengeksekusi perintah yang diberikan melalui shell, maka output dari strace akan berisi semua syscalls eksekusi shell daripada hanya mereka yang dari proses yang menarik.)Selain itu, ketika Anda menjalankan
strace rm ramesh
, shell interaktif tidak berusaha untuk mengganti alias Anda dalam argumen untuk strace, karena itu akan sangat membingungkan bagi semua orang. Shell hanya memperluas alias yang muncul di posisi pertama pada baris perintah.sumber
strace menggunakan
execve c function
sepertifind command
, Namunfind uses exec function
Anda tidak dapat menggunakanaliases
,built-in shell command
atau sebagainya.Kamu harus melakukan:
sumber
Untuk membangun jawaban Stéphane Chazelas, jika Anda mendefinisikan
(dengan spasi di akhir) maka perintah
akan diproses sebagai
Tetapi bahkan ini hanya akan berfungsi untuk kata pertama setelah kata
strace
, jadi itu tidak akan berlaku langsung untuk contoh Anda (di mana Anda memiliki opsi intervensi). Tetapi, jika Anda mendefinisikankemudian
akan diproses sebagai
sumber
Tidak ada alias di sini
Mari kita asumsikan kita memiliki definisi alias
alias rm='rm -i'
di~/.bashrc
. Alias menambahkan opsi untuk meminta sebelum menghapus setiap file:Ini bukan kesalahan
strace
karena tidak menggunakan alias:Tidak ada hubungannya dengan alias.
Di perintah
Kata-kata
rm
dan./file
hanya argumen untuk strace untuk saat ini - shell tidak dapat memperluas aliasrm
, karena tidak dapat mengetahui bahwa strace akan menggunakan argumen ini sebagai perintah nanti.Secara umum, alias perintah hanya dapat digunakan di mana perintah bisa.
Alias adalah fitur dari shell, dan
strace
tidak menggunakan shell sama sekali ketika memanggil perintah dari baris perintah.exec()
Sebagai gantinya, ia menggunakan perintah dan argumen dari baris perintah itu sendiri.Di dalam
strace
, perintah akan dipanggil dengan sesuatu yang miripexec("rm", "file")
, danexec()
akan ditemukan/bin/rm
di PATH - tanpa menggunakan shell.Shell eksplisit
Sekarang, mengapa tidak menyertakan shell dalam
strace
perintah?Hmm ... itu tidak berhasil.
rm
baru saja menghapus file, tanpa-i
prompt.Alias interaktif
Alias biasanya hanya diaktifkan di shell interaktif, baris perintah aktual di terminal.
Dengan alias contoh kami, mudah untuk melihat mengapa itu masuk akal: Jika
rm -i
alias akan diperluas di dalam skrip shell, mereka akan hang pada awalnyarm
tanpa ada yang menekany
.Alias dikendalikan oleh opsi shell
expand_aliases
. Kita dapat mengatur opsi denganbash +O expand_aliases -c ...
. Tapi itu tidak cukup, karena shell non-interaktif juga tidak akan membaca~/.bashrc
. Itu artinya, alias kita tidak hanya dimatikan oleh opsi, tetapi juga tidak ditentukan.Berpura-pura menjadi interaktif
Cara mudah untuk menangani kedua bagian adalah dengan menggunakan opsi baris perintah
-i
untuk membuat shell berpura-pura interaktif:Akhirnya,
-i
alias digunakan!Perhatikan bahwa Anda biasanya tidak menggunakan shell yang berjalan dengan
-i
opsi untuk scripting, bahkan jika Anda ingin memiliki alias Anda tersedia, misalnya.sumber