Điểm:3

Tập lệnh Shell tiếp tục thực thi ngay cả khi đúng

lá cờ in

Tôi có một tập lệnh shell đơn giản để kiểm tra xem người dùng có tồn tại không, nếu không, hãy thêm người dùng đó

#!/usr/bin/bash
tiếng vang "Nhập người dùng"
người dùng đọc -r
nếu [ "$(id -u "$user" &>/dev/null)" = 1 ]; sau đó
  tiếng vang "người dùng đã tồn tại"
khác
  useradd "$user"
  tiếng vang "thêm mật khẩu"
  mật khẩu "$ người dùng"
  tiếng vang "$user" &>>text.txt
  tiếng vang "đã lưu"
fi

Nhưng nó không hiển thị các "người dùng echo tồn tại". thay vào đó nó hiển thị như vậy:

Nhập người dùng

abcdef

useradd: người dùng 'abcdef' đã tồn tại

thêm mật khẩu

Mật khẩu mới: 

Trong trường hợp này abcdef là người dùng hiện có

Xin vui lòng cho tôi biết những gì sai ở đây, cảm ơn rất nhiều.

MatsK avatar
lá cờ mp
Một mẹo để khắc phục sự cố, hãy chạy lệnh `id -u testuser` và kiểm tra xem kết quả có phải là 1 hay không. Vì 1 là thứ duy nhất sẽ dẫn đến `echo "Người dùng tồn tại"`
raj avatar
lá cờ cn
raj
@MatsK Thậm chí 1 sẽ không tiếp tục, vì đầu ra từ `id` được chuyển hướng đến `/dev/null`.
Terrance avatar
lá cờ id
Sau khi bạn kiểm tra `id -u $user &>/dev/null`, hãy sử dụng `echo $?` và điều đó sẽ tạo ra 0 hoặc 1. 0 nghĩa là `mã thoát 0` hoặc true, 1 nghĩa là `mã thoát 1` Hay sai. Hoặc bạn có thể có `if [[ $? == 0 ]]; sau đó`, v.v.
raj avatar
lá cờ cn
raj
@Terrance Đơn giản hơn là chỉ cần sử dụng ngay `id -u $user &>/dev/null` làm điều kiện trong `if`.
Terrance avatar
lá cờ id
@raj không phải trong mọi trường hợp. Trên thực tế, làm điều đó với các câu lệnh `case` hoạt động rất tốt. `id -u` tạo ra số ID người dùng chứ không phải 1 hoặc 0. Vì vậy, xuất `id -u` thành >/dev/null sẽ loại bỏ 1000 nếu đó là ID người dùng.
raj avatar
lá cờ cn
raj
@Terrance Hãy xem câu trả lời của tôi bên dưới. Sử dụng lệnh trực tiếp làm điều kiện để `if` (không cần `$(...)`) kiểm tra mã thoát chứ không phải đầu ra.
Terrance avatar
lá cờ id
@raj Điều đó cũng sẽ hiệu quả. Của tôi chỉ là một cách khác.
Điểm:9
lá cờ cn
raj

Điều kiện sau trong tập lệnh của bạn:

nếu [ "$(id -u "$user" &>/dev/null)" = 1 ]; sau đó

sẽ không bao giờ là sự thật. Nó sẽ là sự thật chỉ có nếu đầu ra mệnh lệnh id -u "$user" &>/dev/null sẽ là một chữ số 1, nhưng vì bất kỳ đầu ra nào từ lệnh đó được chuyển hướng đến /dev/null, điều này sẽ không bao giờ xảy ra.

Thay thế dòng đó bằng

nếu { id -u "$user" &>/dev/null ; } sau đó

Điều kiện này kiểm tra các trạng thái thoát của lệnh (và không phải của nó đầu ra Thích $(...) does) và sẽ đúng nếu lệnh id -u "$user" &>/dev/null thành công (nghĩa là người dùng tồn tại) và sai nếu nó thất bại (nghĩa là người dùng không tồn tại).

lá cờ in
Cảm ơn câu trả lời của bạn, nó hoạt động!!v Nhưng có gì khác nhau giữa [] và {}?
raj avatar
lá cờ cn
raj
`[` là một **lệnh** (tương đương với `test`; xem `man [`) được sử dụng để kiểm tra kết quả của các biểu thức điều kiện khác nhau. `{}` chỉ là dấu ngoặc đơn để đặt lệnh. Trên thực tế, chúng tôi có thể bỏ qua `{}` hoàn toàn (trong khi bạn **không thể** bỏ qua `[]`): `if id -u "$user" &>/dev/null ; then` sẽ hoạt động tốt chỉ là khó đọc hơn.
lá cờ in
Tôi không hiểu `[` là một lệnh để kiểm tra giá trị, sau đó, trong lệnh của tôi '"$(id -u "$user" &>/dev/null)" = 1` tại sao nó không trả về true, ý tôi là , `"$(id -u "$user" &>/dev/null)"` sẽ trả về 0 hoặc 1 phải không?
raj avatar
lá cờ cn
raj
Giá trị của `$(command)` là **đầu ra** của lệnh, tức là. văn bản lệnh in. Bởi vì bạn chuyển hướng đầu ra đó tới `/dev/null`, lệnh sẽ không in được gì. Vì vậy, giá trị của `$(id -u "$user" &>/dev/null)` sẽ luôn là **một chuỗi rỗng**. Bạn so sánh chuỗi trống đó với chữ số 1, không bao giờ có thể trả về giá trị đúng.
lá cờ in
`{` và `}` là không cần thiết. `if id -u "$user" &>/dev/null; thì` là đủ.
raj avatar
lá cờ cn
raj
@JanHudec Tôi biết, nhưng mã rõ ràng hơn với `{}`. Họ ở đó chỉ vì phong cách :)
Điểm:2
lá cờ id

Câu trả lời của @raj là đúng 100% để đơn giản hóa mã.

Đây chỉ là một số cách thay thế để sử dụng mã thoát và có thể làm sáng tỏ thêm một chút về cách sử dụng chúng.

Mã thoát có thể được kiểm tra bằng cách thực hiện một tiếng vang $? ngay sau lệnh của bạn id -u $user &>/dev/null mà không cần phải được bọc trong $(..) hoặc bất cứ điều gì như thế.

Thử xem id -u <tên người dùng> &>/dev/null và sau đó gõ vào tiếng vang $? để kiểm tra mã thoát.

Ví dụ:

terrance@terrance-ubuntu:~$ id -u terrance &>/dev/null
terrance@terance-ubuntu:~$ echo $?
0
terrance@terrance-ubuntu:~$ id -u mark &>/dev/null
terrance@terance-ubuntu:~$ echo $?
1

Trong ví dụ trên, người dùng dấu không tồn tại trên máy tính của tôi, do đó, trạng thái thoát của 1.

Sử dụng mã thoát, bạn có thể đặt nó vào một trường hợp tuyên bố thay vì một nếu khác bản tường trình.

#!/bin/bash
tiếng vang "Nhập tên người dùng"
người dùng đọc -r
id -u "$user" &>/dev/null
trường hợp $? Trong
    0) echo "Người dùng tồn tại";;
    1) người dùng bổ sung $user
       tiếng vang "thêm mật khẩu"
       mật khẩu người dùng $
       tiếng vang $user >> text.txt
       tiếng vang "đã lưu";;
thoát hiểm

Thật thú vị, sử dụng một nếu [ ]; sau đó vẫn có thể được sử dụng bằng cách thêm một tiếng vang $? vào kiểm tra if của bạn, nhưng tôi nhận thấy rằng bạn đang kiểm tra 1 là if tồn tại, nhưng 1 có nghĩa là mã đã thoát với 1 nghĩa là không tìm thấy.

Việc thêm nó cũng sẽ hoạt động như thế này.

#!/bin/bash
tiếng vang "Nhập tên người dùng"
người dùng đọc -r
if [ $(id -u "$user" &>/dev/null; echo $?) == 0 ]; sau đó
    tiếng vang "Người dùng tồn tại"
khác
    người dùng bổ sung $user
    tiếng vang "thêm mật khẩu"
    mật khẩu người dùng $
    tiếng vang $user >> text.txt
    tiếng vang "đã lưu"
fi
lá cờ in
Cảm ơn, tôi học được rất nhiều từ câu trả lời của bạn, nhưng tôi không hiểu tại sao `echo $`, đó là gì ??
Terrance avatar
lá cờ id
@LêQuá»cKhánh Có lẽ điều này ở đây có thể làm sáng tỏ thêm một chút về `echo $?` để kiểm tra các lệnh thoát: https://askubuntu.com/questions/646526/what-is-is-it-a- Biến đổi
Terrance avatar
lá cờ id
@LêQuá»cKhánh Ngoài ra, khi thực hiện kiểm tra là `id -u "$user" &>/dev/null; echo $?` lúc này 2 lệnh là 1.
lá cờ in
Đó là một cuộc sống hack cho shell bash =), cảm ơn bạn rất nhiều
Terrance avatar
lá cờ id
@LêQuá»cKhánh Rất hoan nghênh bạn!
lá cờ in
Tôi có thể hỏi bạn một câu hỏi khác không? Tôi biết `&>` sẽ chuyển thiết bị xuất chuẩn và thiết bị xuất chuẩn sang , nhưng trong trường hợp này tại sao chúng ta cần chuyển các giá trị này sang `/dev/null` , tất cả những gì tôi hiểu bây giờ là `id -u "$user" &>/dev/ null` trả về 0 hoặc 1, sau đó chuyển sang `/dev/null` Nhưng tất cả những gì chúng ta cần là kiểm tra kiểm tra là 0 hoặc 1, nhưng tại sao chúng ta cần chuyển sang `/dev/null` , nếu tôi chỉ sử dụng ` id -u "$user" &>/dev/null` , có chuyện gì vậy? Trên thực tế mã này từ trang web của chúng tôi và không hoàn toàn hiểu
Terrance avatar
lá cờ id
@LêQuá»cKhánh Sử dụng `/dev/null` là một cách cơ bản để xóa thiết bị xuất chuẩn mà bạn nhìn thấy trên màn hình. Nó chỉ là một cách để giữ cho những thứ sạch sẽ. Bạn có thể nhận được mã thoát hoặc trạng thái tương tự mà không cần sử dụng mã đó, nhưng bạn sẽ thấy tất cả mã đó xuất ra màn hình và điều này có thể khiến việc sử dụng mã của bạn trở nên khó khăn hơn. Vui lòng kiểm tra mã của bạn mà không cần `&>/dev/null` vì mã vẫn hoạt động.
Terrance avatar
lá cờ id
@LêQuá»cKhánh 0 và 1 chỉ là trạng thái thoát. Nếu bạn chạy `id -u $user` mà không có bất kỳ thứ gì sau nó, nó sẽ tạo ra số ID người dùng. Giống như tên người dùng của tôi tạo ra 1000 vì đó là số ID người dùng của tôi. Tuy nhiên, nếu tôi nhập `echo $?` sau lệnh đó, nó vẫn sẽ cho kết quả 0 vì trạng thái thoát đã qua.
lá cờ in
cảm ơn nhiều
lá cờ in
Tôi chỉ cố đăng nhập bằng `user1="$(id -u "$user")"` và `echo "User is $user1"` và nó trả về 1007, điều đó có nghĩa là gì?
Terrance avatar
lá cờ id
@LêQuá»cKhánh `id -u` tạo ra UID hoặc số ID người dùng chứ không phải trạng thái thoát. Bạn phải chạy `echo $?` làm lệnh tiếp theo để xem trạng thái thoát của lệnh `id -u` là gì.
lá cờ in
Tôi hiểu bây giờ, cảm ơn bạn rất nhiều

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.