Mungkinkah ada shell login yang tidak interaktif?

11

Dalam menafsirkan diagram alur ini

masukkan deskripsi gambar di sini

Saya menemukan bahwa dalam bash manusia:

Ketika bash dipanggil sebagai shell login interaktif, atau sebagai shell non-interaktif dengan opsi --login, ia pertama kali membaca dan menjalankan perintah dari file / etc / profile, jika file itu ada.

Itu menyatakan bahwa shell login interaktif membaca /etc/profile(tanpa --noprofile)

Juga, kerang non-interaktif dengan opsi --loginbaca/etc/profile

Itu tampaknya meninggalkan beberapa kemungkinan shell login (di mana $0dimulai dengan a -) yang non-interaktif (menjalankan skrip, mungkin sesederhana date) mungkin tidak membaca (sumber) /etc/profile.

Untuk mengkonfirmasi atau menolak ide ini:

Pertama saya mencoba menggunakan su -l -, yang memulai shell login dengan -sebagai karakter pertama tetapi saya gagal membuatnya non-interaktif (dan dapat menyajikan tes untuk menyelidiki itu).

Memanggil sesuatu seperti

$ bash -c 'date' -bash

Tidak melaporkan sebagai shell login (bahkan jika karakter pertama adalah a -).

Coba ini untuk mengungkapkan detailnya:

   $ bash -c 'echo "$0 $- ||$(shopt -p login_shell)||";date' -bash
      -bash hBc ||shopt -u login_shell||
      Fri Aug 19 06:32:31 EDT 2016

The $0memiliki -sebagai karakter pertama, tidak ada i(interaktif) dalam nilai $-tetapi tidak dilaporkan sebagai login_shell(u yang). Dalam hal ini, / etc / profile tidak dibaca, tetapi saya tidak yakin ini adalah tes yang tepat.


Ada juga yang menyebutkan "kerang masuk non-interaktif yang langka" dalam jawaban ini tanpa cukup spesifik untuk pertanyaan ini.


The Kesimpulan dari orang ini adalah bahwa /etc/profileselalu dibaca.

Baca tabel ringkasan: baik shell login interaktif maupun non-interaktif dibaca /etc/profile


Dan, jika contoh dari halaman ini benar:

Some examples

$ su bob                   # interactive non-login shell
$ su - bob                 # interactive login shell
$ exec su - bob            # interactive login shell
$ exec su - bob -c 'env'   # non-interactive login shell
$ ssh bob@example.com      # interactive login shell, `~/.profile`
$ ssh bob@example.com env  # non-interactive non-login shell, `~/.bashrc`

Tes exec su - bob -c 'env'laporan yang /etc/profiledibaca.


Pendeknya:

Apakah mungkin untuk memiliki shell login non-interaktif (tidak dipanggil dengan --login atau -l)?

Dan jika benar, apakah itu membaca /etc/profilefile?

Jika hal di atas benar, kita harus menyimpulkan bahwa SEMUA shell login [interaktif (atau tidak)] membaca / etc / profile (tanpa --noprofileopsi).

Catatan: untuk mendeteksi bahwa / etc / profile sedang dibaca, cukup tambahkan di awal file perintah ini:

echo "'/etc/profile' is being read"
Komunitas
sumber

Jawaban:

2

Shell login non-interaktif tidak biasa, tetapi mungkin. Jika Anda memulai shell dengan argumen nol (yang biasanya merupakan nama yang dapat dieksekusi) yang disetel ke string yang dimulai dengan a -, ini adalah shell login, apakah itu interaktif atau tidak.

$ ln -s /bin/bash ./-bash
$ echo 'shopt -p login_shell; echo $-' | HOME=/none PATH=.:$PATH -bash
shopt -s login_shell
hB

Upaya Anda bash -c date -bashtidak berhasil karena itu tidak memberi tahu shell untuk menjadi shell login: argumen zeroth adalah bash, tidak -bash. Setelah pesta telah dimulai, ia menetapkan variabel $0untuk -bashbukan argumen ke nol, tetapi argumen ke nol adalah apa yang penting.

Anda dapat menjalankan shell login noninteraktif dengan su -latau su -, tetapi Anda perlu mengatur input standar agar tidak menjadi terminal sementara masih dapat diotorisasi (tanpa harus mengetikkan kata sandi, atau mengatur kata sandi Anda pada awal memasukkan). Mungkin lebih mudah dengan sudo: jalankan sudo trueuntuk mendapatkan kredensial kehadiran, kemudian saat kredensial masih berjalan echo 'shopt -p login_shell; echo $-' | sudo -i.

Lihat juga Perbedaan antara Shell Login dan Shell Non-Login?

Gilles 'SANGAT berhenti menjadi jahat'
sumber
4

Saya telah melihat lingkungan masuk grafis yang berfungsi:

exec "$SHELL" -l -c 'exec start-window-or-session-manager'

atau setara dengan:

exec -a "-$SHELL" "$SHELL" <<EOF
exec start-window-or-session-manager
EOF

Sehingga file inisialisasi sesi (seperti ~/.profileuntuk shell mirip Bourne (dan yang sesuai /etcuntuk beberapa)) dibaca dan diterapkan.

Yang pertama tidak bekerja dengan semua cangkang. -ldidukung oleh sejumlah besar shell, tetapi tidak semua, dan pada beberapa, seperti csh/ tcsh, tidak dapat digunakan dengan -c. Karakter pertama argv[0]makhluk -dipahami oleh semua shell, karena itulah yang logindigunakan untuk memberi tahu shell bahwa mereka shell login.

Dalam kasus kedua, stdin dari shell itu adalah sesuatu yang bukan ttyperangkat ( <<diimplementasikan oleh file reguler sementara, atau pipa tergantung pada shell), sehingga shell tidak interaktif (definisi makhluk interaktif ketika manusia berinteraksi dengan itu).

Stéphane Chazelas
sumber
Yang pertama menggunakan --loginopsi. Untuk yang kedua, jika saya exec -a "-bash" "bash" <<<"shopt -p login_shell; echo $0 $-"mendapatkan (disandikan dalam C qoutes) $'/etc/profile read\nshopt -s login_shell\nbash himBH'demikian, ini adalah login tetapi interaktif. Kami membutuhkan login dan non-interaktif . Apa yang saya lewatkan?
@sorontar, dengan <<<"$-", yang $-diperluas oleh shell panggilan karena tanda kutip ganda. Shell yang disebut tidak interaktif karena stdinnya bukan tty.
Stéphane Chazelas
Ah, ya, Anda benar, Pak. Namun, memperbaiki kesalahan, kita bisa melakukan ini: exec -a "-bash" "bash" <<\EOF shopt -p login_shell; echo $0 $- EOFuntuk mendapatkan konfirmasi ini: $'/etc/profile read stdin: is not a tty shopt -s login_shell -bash hB'Jadi, ya, shell login non-interaktif adalah mungkin, dan masih dibaca /etc/profile. Haruskah kita menyimpulkan bahwa SEMUA shell login membaca /etc/profile?
ksh membuatnya sangat jelas bahwa ini adalah shell login non-interaktif , coba exec -a "-ksh" "ksh" <<\EOF echo $0; set -o EOF, :).
1
@sorontar, saya pikir Anda dapat mengharapkan sebagian besar implementasi shell untuk membaca file inisialisasi sesi mereka ketika dipanggil sebagai shell login. Yang mana mereka tergantung pada implementasi dan versi shell. Dalam hal bashpenanganan file start-up cukup kacau IMO, Anda akan menemukan bahwa beberapa sistem telah menambalnya untuk memiliki perilaku yang lebih masuk akal menambahkan variasi lebih banyak.
Stéphane Chazelas
3

Ya, shell login non-interaktif dimungkinkan

$ head -1 /etc/profile
echo PROFILE BEING READ

$ echo echo hello | su -
PROFILE BEING READ
stdin: is not a tty
hello

$
Stephen Harris
sumber
Yang mirip dengan ini disederhanakan: su -c 'echo hello' -. Yang, untuk menguji apa yang kita butuhkan, harus ditulis sebagai: su -c 'echo $0 $-; shopt -p login_shell' -untuk mendapatkan jawaban ini mengkonfirmasikan (dikodekan dalam tanda kutip C): $'/etc/profile read \n -su hBc \n shopt -s login_shell'. Itu mengonfirmasi bahwa shell non-interaktif masuk dikecualikan dan bahwa, dalam proses, / etc / profile telah dibaca. Terima kasih.
0

Apakah mungkin untuk memiliki shell login non-interaktif (tidak dipanggil dengan --login atau -l)?

IYA.

$ (exec -a '-' bash -c 'shopt -q login_shell && echo login shell')

Namun, perhatikan bahwa /etc/profiletidak akan digunakan untuk shell login yang tidak berinteraksi kecuali --loginargumen diberikan.

Idiom umum yang menggunakan shell login non-interaktif adalah:

$ su - someuser -c somecommand

Tapi ini menderita fakta yang /etc/profiletidak bisa dieksekusi.

Dimungkinkan untuk mengubah perilaku ini tetapi melibatkan mengubahsuaikan kode sumber Bash pada waktu kompilasi dengan membatalkan komentar opsi yang ditemukan di config-top.h :

/* Define this to make non-interactive shells begun with argv[0][0] == '-'
run the startup files when not in posix mode. */
/* #define NON_INTERACTIVE_LOGIN_SHELLS */

Ketika saya meneliti suanomali ini , saya menemukan bahwa cangkang lain termasuk zshdan dashtidak memiliki perbedaan ini.

starfry
sumber