Có thể có một vỏ đăng nhập không tương tác?


11

Khi giải thích sơ đồ này

nhập mô tả hình ảnh ở đây

Tôi thấy rằng trong bash man:

Khi bash được gọi dưới dạng shell đăng nhập tương tác hoặc dưới dạng shell không tương tác với tùy chọn --login, trước tiên, nó sẽ đọc và thực thi các lệnh từ tệp / etc / profile, nếu tệp đó tồn tại.

Điều đó nói rằng các vỏ đăng nhập tương tác đọc /etc/profile(không có --noprofile)

Ngoài ra, shell không tương tác với tùy chọn --loginđọc/etc/profile

Điều đó dường như để lại một số shell đăng nhập có thể (trong đó $0bắt đầu bằng a -) không tương tác (chạy tập lệnh, có thể đơn giản như date) có thể không đọc (nguồn) /etc/profile.

Để xác nhận hoặc từ chối ý tưởng này:

Đầu tiên tôi đã thử sử dụng su -l -, nó bắt đầu một vỏ đăng nhập với -ký tự đầu tiên nhưng tôi không làm cho nó không tương tác (và có thể trình bày các thử nghiệm để thăm dò nó).

Gọi một cái gì đó như

$ bash -c 'date' -bash

Không báo cáo là shell đăng nhập (ngay cả khi ký tự đầu tiên là a -).

Hãy thử điều này để tiết lộ chi tiết:

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

$0một -ký tự đầu tiên, không có i(tương tác) trong giá trị của $-nhưng nó không được báo cáo là một login_shell(-u). Trong trường hợp này, / etc / profile không được đọc, nhưng tôi không chắc đây là bài kiểm tra đúng.


Ngoài ra còn có đề cập đến "vỏ đăng nhập không tương tác hiếm" trong câu trả lời này mà không đủ cụ thể cho câu hỏi này.


Các kết luận của anh chàng này/etc/profileluôn đọc.

Đọc bảng tóm tắt: cả vỏ đăng nhập tương tác và không tương tác đều đọc /etc/profile


Và, nếu các ví dụ từ trang này là chính xác:

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`

Các bài kiểm tra exec su - bob -c 'env'báo cáo /etc/profileđã được đọc.


Nói ngắn gọn:

Có thể có một vỏ đăng nhập không tương tác (không được gọi bằng --login hoặc -l) không?

Và nếu đúng, nó đang đọc /etc/profiletập tin?

Nếu điều trên là đúng, chúng ta phải kết luận rằng TẤT CẢ các shell đăng nhập [tương tác (hoặc không)] đọc / etc / profile (không có --noprofiletùy chọn).

Lưu ý: để phát hiện / etc / profile đang được đọc, chỉ cần thêm vào đầu tập tin lệnh này:

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

Câu trả lời:


2

Một vỏ đăng nhập không tương tác là bất thường, nhưng có thể. Nếu bạn khởi động shell với đối số zeroth (thường là tên của tệp thực thi) được đặt thành một chuỗi bắt đầu bằng một -, thì đó là shell đăng nhập, cho dù đó có tương tác hay không.

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

Nỗ lực của bạn bash -c date -bashkhông hoạt động vì điều đó không bảo shell là vỏ đăng nhập: đối số zeroth là bashkhông -bash. Sau khi bash đã bắt đầu, nó đặt biến $0thành -bashthay vì đối số zeroth, nhưng đối số zeroth mới là vấn đề quan trọng.

Bạn có thể chạy shell đăng nhập không tương tác với su -lhoặc su -, nhưng bạn cần sắp xếp để đầu vào tiêu chuẩn không phải là thiết bị đầu cuối trong khi vẫn có thể được ủy quyền (mà không phải nhập mật khẩu hoặc sắp xếp mật khẩu của bạn khi bắt đầu đầu vào). Có thể dễ dàng hơn với sudo: chạy sudo trueđể có được thông tin hiện diện, sau đó trong khi thông tin xác thực vẫn chạy hợp lệ echo 'shopt -p login_shell; echo $-' | sudo -i.

Xem thêm Sự khác biệt giữa Shell đăng nhập và Shell không đăng nhập?


4

Tôi đã thấy môi trường đăng nhập đồ họa làm:

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

hoặc tương đương với:

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

Vì vậy, tệp khởi tạo phiên (như ~/.profileđối với shell giống Bourne (và các tệp tương ứng trong /etcmột số)) được đọc và áp dụng.

Cái đầu tiên không hoạt động với tất cả các vỏ. -lđược hỗ trợ bởi một số lượng lớn các shell, nhưng không phải tất cả, và trên một số, như csh/ tcsh, không thể được sử dụng với -c. Mặc dù vậy, ký tự đầu tiên argv[0]được -hiểu bởi tất cả các shell, vì đó là những gì loginsử dụng để nói với các shell mà chúng là các shell đăng nhập.

Trong trường hợp thứ hai, stdin của shell đó là một cái gì đó không phải là một ttythiết bị ( <<được thực hiện bởi một tệp thông thường tạm thời hoặc một đường ống tùy thuộc vào vỏ), do đó, vỏ không tương tác (định nghĩa về tương tác khi con người tương tác với nó).


Cái đầu tiên là sử dụng --logintùy chọn. Đối với cái thứ hai, nếu tôi exec -a "-bash" "bash" <<<"shopt -p login_shell; echo $0 $-"nhận được (được mã hóa trong C qoutes) $'/etc/profile read\nshopt -s login_shell\nbash himBH'thì đó là thông tin đăng nhập nhưng nó là tương tác. Chúng tôi cần đăng nhập và không tương tác . Tôi đang thiếu cái gì vậy?

@sorontar, với <<<"$-", $-được mở rộng bởi vỏ gọi vì dấu ngoặc kép. Shell được gọi là không tương tác vì stdin của nó không phải là một tty.
Stéphane Chazelas

À, vâng, bạn đúng, thưa ngài. Tuy nhiên, sửa lỗi, chúng ta có thể làm điều này: exec -a "-bash" "bash" <<\EOF shopt -p login_shell; echo $0 $- EOFđể có được xác nhận này: $'/etc/profile read stdin: is not a tty shopt -s login_shell -bash hB'Vì vậy, có, một vỏ đăng nhập không tương tác là có thể, và nó vẫn đọc /etc/profile. Chúng ta có nên kết luận rằng TẤT CẢ các vỏ đăng nhập đã đọc /etc/profile?

ksh làm cho nó khá rõ ràng rằng nó là một vỏ đăng nhập không tương tác , hãy thử exec -a "-ksh" "ksh" <<\EOF echo $0; set -o EOF, :).

1
@sorontar, tôi nghĩ rằng bạn có thể mong đợi hầu hết các cài đặt shell sẽ đọc (các) tệp khởi tạo phiên của chúng khi được gọi là shell đăng nhập. Mà chúng phụ thuộc vào việc thực hiện shell và phiên bản. Trong trường hợp bash, việc xử lý tệp khởi động là IMO khá lộn xộn, bạn sẽ thấy rằng một số hệ thống đã vá nó để có hành vi hợp lý hơn, thậm chí còn có nhiều biến thể hơn.
Stéphane Chazelas

3

Có, vỏ đăng nhập không tương tác là có thể

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

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

$

Điều đó tương tự như đơn giản hóa này : su -c 'echo hello' -. Trong đó, để kiểm tra những gì chúng ta cần, nên được viết là: su -c 'echo $0 $-; shopt -p login_shell' -để có được câu trả lời xác nhận này (được mã hóa trong dấu ngoặc kép C) : $'/etc/profile read \n -su hBc \n shopt -s login_shell'. Điều đó xác nhận rằng một vỏ không tương tác đăng nhập đã bị loại bỏ và trong quá trình, / etc / profile đã được đọc. Cảm ơn.

0

Có thể có một vỏ đăng nhập không tương tác (không được gọi bằng --login hoặc -l) không?

ĐÚNG.

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

Tuy nhiên, lưu ý rằng /etc/profilesẽ không được sử dụng cho vỏ đăng nhập không tương tác trừ khi --loginđối số được đưa ra.

Một thành ngữ phổ biến gọi vỏ đăng nhập không tương tác là:

$ su - someuser -c somecommand

Nhưng điều này chịu đựng thực tế là /etc/profilekhông được thực thi.

Có thể thay đổi hành vi này nhưng nó liên quan đến việc tùy chỉnh mã nguồn Bash tại thời gian biên dịch bằng cách bỏ qua một tùy chọn có trong 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 */

Khi tôi nghiên cứu susự bất thường này , tôi thấy rằng các vỏ khác bao gồm zshdashkhông có sự khác biệt này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.