Giải thích giúp vài dòng code Shell script Ubuntu

Em có file count.sh nội dung như sau:

echo "Enter filename: \c"
read fname
terminal=`tty` 
exec < $fname

nol=0
now=0

while read line
do
	nol=`expr $nol + 1`
	set $line
	now=`expr $now + $#`
done

echo "Number of lines: $nol"
echo "Number of words: $now"

exec < $terminal

```terminal=`tty```` nghĩa là gì?

Ban đầu có exec < $fname
cuối file có dòng exec < $terminal để làm gì? Trong khi thử bỏ dòng cuối cùng đi vẫn run bình thường.

Giải thích giúp em 2 cái trên thôi ạ, còn lại em cũng hiểu được rồi.

1 Like

terminal=tty nghĩa là gì?

Lưu filename đang connect tới standard in (man tty).

Ban đầu có exec < $fname
cuối file có dòng exec < $terminal để làm gì? Trong khi thử bỏ dòng cuối cùng đi vẫn run bình thường.

Ngắn gọn là nội dung của $fname sẽ là standard in của script (Đọc tài liều của shell đang dùng, tìm hàm exec built-in).

exec < $terminal sẽ trả lại standard in của script như ban đầu.

Một số điều chưa đúng

  • Sử dụng backstick cho command substitution thay vì $(...), xem tại đây.
  • Không double quotes biến: đây là lỗi hay gặp nhất. Thử tưởng tượng exec < $fname có chạy không nếu $fname chứa space hay kí tự đặc biệt? Không double quotes biến dẫn tới nhiều lỗ hổng về security và giảm hiệu năng của chương trình. Hãy nhớ một điều: “Luôn luôn double quotes biến trong POSIX shell (trừ zsh) nếu không muốn split+glob”.
  • Sử dụng while + read chưa đúng: về cơ bản, để đọc file line-by-line trong shell, cần while IFS= read -r line, xem chi tiết tại đây.
  • Sử dụng expr cho tính toán: sử dụng ((...)) để dễ đọc, hiểu, sử dụng $((...)) cho portability.
8 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?