Một vài lưu ý khi sử dụng Shell Script (phần 1)
I. 2>&1 hoạt động ra sao ? Khi lập trình, chúng ta thường sử dụng một số câu lệnh như điều đương nhiên để giải quyết một vấn đề, nhưng lại không hiểu rõ bản chất của chúng. Với Shell Script cũng vậy, có những thứ phổ biến đến mức chúng ta chỉ việc dùng mà chả tìm hiểu thế nghĩa là sao, ví ...
I. 2>&1 hoạt động ra sao ?
Khi lập trình, chúng ta thường sử dụng một số câu lệnh như điều đương nhiên để giải quyết một vấn đề, nhưng lại không hiểu rõ bản chất của chúng. Với Shell Script cũng vậy, có những thứ phổ biến đến mức chúng ta chỉ việc dùng mà chả tìm hiểu thế nghĩa là sao, ví dụ như 2>&1.
ls foo > /dev/null 2>&1
Hãy thử tìm hiểu kỹ hơn một chút nhé.
I/O redirection
Redirection là kỹ thuật được sử dụng để ghi kết quả đầu ra của một câu lệnh sang địa chỉ khác. Ví dụ khi ta cat một file, output sẽ được in lên màn hình như sau:
$ cat foo.txt foo bar baz
Tuy nhiên nếu ta redirect sang địa chỉ khác, ví dụ như một file tên là output.txt thì:
$ cat foo.txt > output.txt $ cat output.txt foo bar baz
Để ý thấy dòng cat đầu tiên không hề có output ra màn hình, vì chúng ta đã chuyển standard output (stdout) sang file output.txt.
Ngoài ra, khi chương trình cần gửi error messages, nó sẽ tìm đến standard error (stderr). Giờ chúng ta thử cat một file không tồn tại:
$ cat nop.txt > output.txt cat: nop.txt: No such file or directory
Mặc dù chúng ta đã redirect stdout sang một file, nhưng error vẫn được ghi ra màn hình, vì chúng ta mới chỉ redirect standard output chứ chưa redirect standard error.
File descriptors
Một file descriptor là một số nguyên dương đại diện cho một file đang được mở. Nếu bạn có 100 files đang được mở, bạn sẽ có 100 file descriptors cho chúng.
Trong hệ thống Unix, mọi thứ đều là một file, do đó tồn tại file descriptor cho standard ouput (id = 1) và cho standard error (id =2).
2>&1
Quay lại với ví dụ ban đầu, khi chúng ta redirect ouput của câu lệnh cat sang một file. Chúng ta có thể viết lại nó như sau:
$ cat foo.txt 1> output.txt
1 ở đây là file descriptor của stdout.
Do đó, để redirect stderr, chúng ta chỉ việc sử dụng đúng file descriptor:
$ cat nop.txt 2> error.txt $ cat error.txt cat: nop.txt: No such file or directory
Ở thời điểm này, có lẽ mọi người cũng bắt đầu hiểu được 2>&1 hoạt động ra sao rồi chứ nhỉ?
&1 ám chỉ giá trị của file descriptor 1 (stdout), nên 2>&1 có nghĩa là "redirect stderr đến cùng địa điểm với stdout đang được redirect".
$ cat foo.txt > output.txt 2>&1 $ cat output.txt foo bar baz $ cat nop.txt > output.txt 2>&1 $ cat output.txt cat: nop.txt: No such file or directory
Tổng kết
- Chương trình sẽ gửi output đến hai nơi: Standard output (stdout) và Standard Error (stderr)
- Có thể redirect những outputs đó đến nơi khác (ví dụ như đến một file nào đó)
- File descriptors cho stdout là 1, cho stderr là 2
- command > output là cách viết tắt cho command 1> output
- Có thể sử dụng &[FILE_DESCRIPTOR] để đại diện cho giá trị của một file descriptor
- 2>&1 sẽ redirect stderr đến giá trị đang được set cho stdout
Source: Understanding Shell Script's idiom: 2>&1