man su
mengatakan:
You can use the -- argument to separate su options from the arguments
supplied to the shell.
man bash
mengatakan:
-- A -- signals the end of options and disables further option
processing. Any arguments after the -- are treated as filenames
and arguments. An argument of - is equivalent to --.
Baiklah, mari kita lihat:
[root ~] su - yuri -c 'echo "$*"' -- 1 2 3
2 3
[root ~] su - yuri -c 'echo "$*"' -- -- 1 2 3
2 3
[root ~] su - yuri -c 'echo "$*"' -- - 1 2 3
1 2 3
[root ~] su - yuri -c 'echo "$*"' - 1 2 3
1 2 3
Apa yang saya harapkan (output dari perintah kedua berbeda):
[root ~] su - yuri -c 'echo "$*"' -- 1 2 3
2 3
[root ~] su - yuri -c 'echo "$*"' -- -- 1 2 3
1 2 3
[root ~] su - yuri -c 'echo "$*"' -- - 1 2 3
1 2 3
[root ~] su - yuri -c 'echo "$*"' - 1 2 3
1 2 3
Mungkin tidak banyak masalah. Tetapi apa yang terjadi di sana? Varian kedua dan ketiga sepertinya cara untuk pergi, tetapi salah satu dari mereka tidak bekerja. Yang keempat sepertinya tidak -
bisa diandalkan, bisa diperlakukan sebagai su
pilihan.
bash 4.2.45
akun sumber dan tujuan.Jawaban:
Apa yang terjadi adalah bahwa argumen pertama yang Anda berikan ke shell adalah
$0
parameter, (biasanya ini akan menjadi nama shell). Itu tidak termasuk ketika Anda melakukannyaecho $*
karena$*
setiap argumen terpisah$0
.Contoh:
Memperbarui
Melakukan perintah berikut:
menghasilkan garis strace:
Jadi entah bagaimana tampaknya dalam hal
su
ini melahap ekstra--
tanpa melewatkannya ke bash, mungkin karena bug (atau setidaknya perilaku tidak berdokumen). Namun itu tidak akan memakan lebih dari dua--
argumen:sumber
su - yuri -c 'echo "$*"' -- -- 1 2 3
:, shell seharusnya mendapat-- 1 2 3
, tetapi output saja2 3
. Apakah itu masuk akal?bash -c 'echo $*' -- 1 2 3
, output1 2 3
seperti yang diharapkan.su
bug.Sebenarnya jawaban @ Graeme - dan pertanyaan Anda - hanya referensi efek samping dari bagaimana shell menangani
"$@positional $*parameters".
ini ditugaskan oleh shell untuk argumen atas doa dan setiap saat kemudian dengan built-inset
utilitas. Mereka dapat dipanggil kapan saja dengan"$*"
yang membagi setiap posisi dengan karakter pertama"$IFS"
atau"$@"
yang mengutip setiap posisi dan membaginya dengan semua"$IFS."
Jika Anda sudah memiliki nilai yang Anda makan shell, Anda tidak perlu
--
tiga kali. Parameter Shellset
dapat - selalu, kapan saja, tidak hanya saat pemanggilan (kecuali $ 0 dan -i):Dan semua kutipan shell bisa membingungkan. Ini menyederhanakan sedikit hal:
Argumen shell induk adalah
set
untuk 4, 5, dan 6 dan kemudian diteruskan ke subkulit yang dipanggil olehsu
via positionalparameter "$@array".
Perhatikan bagaimana saya
( subshell )
perintah di atas - Saya melakukannya karena saya tidak ingin dipusingkan dengan lingkungan shell saya saat ini - karena saya secara tidak sengaja dapat mengubah sesuatu yang saya lebih suka tidak melakukannya jika saya melakukannya denganset.
TENTANG REDIRECTION:
Pertama-tama, sistem Unix Anda berfungsi dengan file - izin file, konten file, atribut file. Dalam satu atau lain cara, setiap objek data yang Anda gunakan dapat (dan, setidaknya menurut saya, harus) ditangani sebagai file. Pengalihan menunjuk ke file - itu saja. A
<<HERE-DOCUMENT
akan menjelaskan file in-line kemudian mengarahkan ulang. Entah ekspansi shell ditafsirkan atau tidak.Penanya mencatat dalam komentar di bawah ini bahwa ketika ia mencoba menggunakan metode ini sebagai
root
pengguna, ia akan diberikan kesalahan izin. Ketika saya menjawab saya menyarankan diachown
atauchgrp
yang/dev/fd/${num}
file khusus, tapi ini mungkin bukan metode terbaik. Alasan dia menemukan masalah iniroot
adalah diberikanread
izin tetapi bukanexecute
izin. Anda dapat dengan mudah menangani ini hanya dengan menghindariexec
panggilan. Alih-alih memohon/dev/fd/${num}
file secara langsung pada baris perintah, lakukan:Menggunakan dua heredocs dapat membantu melarikan diri. Inilah yang terjadi dalam setiap kasus:
TANPA SETELAH
<<HEREDOC
KELUARAN
SET
"$@"
IN<<HEREDOC
KELUARAN
SET
"$@"
DAN LEBIH DALAM<<HEREDOC
KELUARAN
sumber
"8 9\n4 5 6\n"
. Saya sedang berlaridebian 6
,bash-4.1.5
dansu
.root
itu mengatakan:-su: /dev/fd/4: Permission denied
. Ngomong-ngomong, apa maksudnya? Kalau tidak, output seperti yang Anda katakan, tetapi tidak menjawab pertanyaan. Pertanyaannya adalah tentang menggunakan--
dan-
.chown /dev/fd/4
selama Anda akan membutuhkannya, atau hanyachgrp
. Saya tidak punya banyak waktu untuk menguji sekarang. Tapi itu sedikit di luar intinya, seperti yang lain Anda tidak perlu memberikan argumen di ujung ekor sama sekali - hanya bekerja kutipan Anda. Lihat sekarang?su
karena tidak dapat bekerja dengan dialihkanstdin
, melewati argumen masih lebih baik daripada memasukkannya ke dalam perintah. Karena dalam kasus terakhir Anda perlu melarikan diri dari mereka.