Ngạc nhiên thay, khiến máy tính cho output dễ đọc cho con người không dễ dàng. Với sự giới thiệu của standard streams và cụ thể standard output, chương trình có cách nói chuyện với nhau dùng plain text stream. Nhưng humanizing và hiển thị stdout là chuyện khác. Công nghệ qua thời đại computing đã cố gắng giải quyết vấn đề này, từ dùng ký tự ASCII trong video display đến lệnh shell hiện đại như echo và printf.
Những tiến bộ này không liền mạch. Việc in output ra terminal đầy rẫy quirk cho lập trình viên, như việc mở rộng escape sequence để in newline. Việc mở rộng placeholder \n có thể thực hiện nhiều cách, mỗi cách có lịch sử và phức tạp riêng.
Dùng echo
Từ khi xuất hiện trong Multics đến sự phổ biến ngày nay trên hệ thống Unix-like, echo vẫn là công cụ quen thuộc khiến terminal nói "Hello world!" Đáng tiếc, implementation không nhất quán across OS làm dùng nó trở nên tricky. echo trên một số hệ thống tự động mở rộng escape sequence, những hệ khác cần tùy chọn -e để làm cùng việc:
echo "the study of European nerves is \neurology"
# the study of European nerves is \neurology
echo -e "the study of European nerves is \neurology"
# the study of European nerves is
# eurology
Do sự không nhất quán implementation, echo được coi là non-portable. Ngoài ra, dùng nó với user input dễ bị corrupt qua shell injection attack dùng command substitution.
Trong hệ thống hiện đại, nó chỉ giữ lại để tương thích với nhiều chương trình vẫn dùng nó. Đặc tả POSIX khuyến nghị dùng printf trong chương trình mới.
Dùng printf
Kể từ Unix Edition 4, lệnh printf portable về cơ bản là echo mới và tốt hơn. Nó cho phép dùng format specifier để humanize input. Để interpret backslash escape sequence, dùng %b. Ký tự sequence \n đảm bảo output kết thúc bằng newline:
printf "%b\n" "Many females in Oble are \noblewomen"
# Many females in Oble are
# oblewomen
Mặc dù printf có thêm option làm nó thay thế echo mạnh mẽ hơn, tiện ích này không hoàn hảo và có thể bị uncontrolled format string attack. Lập trình viên quan trọng phải xử lý cẩn thận user input.
Đặt newline trong biến
Trong nỗ lực cải thiện portability giữa compiler, tiêu chuẩn ANSI C được thiết lập 1983. Với ANSI-C quoting dùng $'...', escape sequence được thay thế trong output theo tiêu chuẩn.
Điều này cho phép lưu string có newline trong biến và in ra với newline được interpret. Làm bằng cách set biến, sau đó gọi nó với printf dùng $:
puns=$'\number\narrow\nether\nice'
printf "%b\n" "These words started with n but don't make $puns"
# These words started with n but don't make
# umber
# arrow
# ether
# ice
Biến mở rộng được single-quoted, truyền literal cho printf. Như luôn, quan trọng phải xử lý input đúng cách.
Bonus: Shell Parameter Expansion
Trong bài giải thích Bash và braces, tôi nói về phép màu của shell parameter expansion. Chúng ta có thể dùng expansion ${parameter@operator} để interpret escape sequence. Dùng printf specifier %s in as string, và operator E sẽ mở rộng escape sequence trong biến:
printf "%s\n" ${puns@E}
# umber
# arrow
# ether
# ice
Thách thức liên tục của việc nói chuyện như người
String interpolation tiếp tục là bài toán khó cho lập trình viên. Bên cạnh việc khiến ngôn ngữ và shell đồng ý về ý nghĩa placeholder, dùng đúng escape sequence đòi hỏi mắt tinh tế.
String interpolation kém có thể dẫn đến output trông ngốc nghếch, cũng như giới thiệu lỗ hổng bảo mật, như injection attacks. Cho đến khi tiến hóa tiếp theo của terminal cho chúng ta nói bằng emoji, chúng ta nên chú ý khi in output cho con người.