Shell của bạn đang diễn giải các trích dẫn, cả '
và "
trước khi chúng đến echo
. Tôi thường chỉ đặt dấu ngoặc kép xung quanh đối số của mình để lặp lại ngay cả khi chúng không cần thiết; ví dụ:
$ echo "Hello world"
Hello world
Vì vậy, trong ví dụ đầu tiên của bạn, nếu bạn muốn bao gồm các dấu ngoặc kép trong đầu ra của mình, chúng cần phải được thoát:
$ echo \'Hello world\'
'Hello world'
Hoặc chúng cần được sử dụng trong một đối số được trích dẫn (nhưng nó không thể là cùng một loại trích dẫn, hoặc bạn sẽ cần phải thoát nó bằng mọi cách):
$ echo "'Hello world'"
'Hello world'
$ echo '"Hello world"'
"Hello world"
Trong ví dụ thứ hai của bạn, bạn đang chạy thay thế lệnh ở giữa chuỗi:
grep $ARG /var/tmp/setfile | awk {print $2}
Những thứ bắt đầu $
cũng được xử lý đặc biệt bởi shell - nó coi chúng là các biến và thay thế chúng bằng các giá trị của chúng. Vì rất có thể cả hai biến đó đều không được đặt trong trình bao của bạn, nên nó thực sự chỉ chạy
grep /var/tmp/setfile | awk {print}
Kể từ khi grep
chỉ nhìn thấy một đối số, nó giả định rằng đối số đó là mẫu bạn đang tìm kiếm và vị trí mà nó sẽ đọc dữ liệu từ đó là stdin, vì vậy nó chặn chờ đầu vào. Đó là lý do tại sao lệnh thứ hai của bạn dường như bị treo.
Điều này sẽ không xảy ra nếu bạn trích dẫn một đối số (đó là lý do tại sao ví dụ đầu tiên của bạn gần như hoạt động), vì vậy đây là một cách để có được đầu ra bạn muốn:
echo \'' echo PARAM=` grep $ARG /var/tmp/setfile | awk '{print $2}' ` '\'
Bạn cũng có thể trích dẫn hai lần, nhưng sau đó bạn sẽ cần thoát $
s để shell không giải quyết chúng dưới dạng các biến và backticks để shell không chạy thay thế lệnh ngay lập tức:
echo "' echo PARAM=\` grep \$ARG /var/tmp/setfile | awk '{print \$2}' \` '"