Tại sao một bash ở đây-chuỗi thêm một char dòng mới theo dõi?


34

Các ví dụ sau đây cho thấy một dòng mới được thêm vào chuỗi ở đây .
Tại sao điều này được thực hiện?

xxd -p <<<'a'  
# output: 610a

xxd -p <<<'a
'
# output: 610a0a

Câu trả lời:


38

Câu trả lời dễ dàng là vì ksh được viết theo cách đó (và bash tương thích). Nhưng có một lý do cho sự lựa chọn thiết kế đó.

Hầu hết các lệnh mong đợi nhập văn bản. Trong thế giới unix, một tệp văn bản bao gồm một chuỗi các dòng, mỗi dòng kết thúc bằng một dòng mới . Vì vậy, trong hầu hết các trường hợp, một dòng mới cuối cùng là bắt buộc. Một trường hợp đặc biệt phổ biến là lấy đầu ra của lệnh bằng lệnh susbtlation, xử lý nó theo một cách nào đó, sau đó chuyển nó sang lệnh khác. Lệnh thay thế dải mới dòng cuối cùng; <<<đặt một trở lại.

tmp=$(foo)
tmp=${tmp//hello/world}
tmp=${tmp#prefix}
bar <<<$tmp

Bash và ksh không thể thao túng dữ liệu nhị phân (dù sao nó không thể đối phó với các ký tự null), vì vậy không có gì đáng ngạc nhiên khi các cơ sở của chúng hướng đến dữ liệu văn bản.

Các <<<cú pháp ở đây-string là chủ yếu chỉ để thuận tiện dù sao, như <<ở đây-tài liệu. Nếu bạn không cần thêm một dòng mới cuối cùng, hãy sử dụng echo -n(trong bash) hoặc printfvà một đường ống dẫn.


Càng kỹ càng hơn câu trả lời của tôi
Mike

2
Bash có thể đã mượn chuỗi ở đây từ ksh93, nhưng ksh đã lần lượt mượn chúng từ zsh, thứ đã lấy chúng từ chiếc RC shell Plan 9 .
Mark Reed

2
<<<được giới thiệu với thế giới Bourne bởi zsh, không ksh. Và nó được lấy cảm hứng từ một nhà điều hành tương tự tại cảng Unix của rcmà đã không nói thêm rằng thêm ký tự xuống dòng. Thật thú vị, =(<<<text)nhà điều hành không thêm dòng mới vào zsh.
Stéphane Chazelas

Nếu bạn thắc mắc về sự quan tâm trong câu trả lời này là vì câu hỏi này trong SO .
fedorqui

1
Có cách nào để viết chuỗi ở đây (mà không sử dụng bất kỳ tiện ích nào khác như printf, v.v.) để tránh dòng mới trong đuôi bashkhông? Giống như @ StéphaneChazelas nhọn là có thể trong zsh.
CTodea

3

Một kịch bản trong đó thực tế là có các dòng mới được thêm vào đây - chuỗi là khi sử dụng readlệnh khi set -echế độ được kích hoạt. Nhớ lại set -ekhiến kịch bản chấm dứt khi nó (nhiều hơn hoặc ít hơn) gặp các câu lệnh tạo mã trạng thái khác không. Hãy xem xét việc readtạo mã trạng thái khác không khi nó gặp một chuỗi không có dòng mới:

#!/bin/bash
set -e

# The following statement succeeds because here-strings append a newline:
IFS='' read -r <<< 'newline appended'
echo 'Made it here'

# The following statement fails because 'read' returns a non-zero status
# code when no newlines are encountered.
printf 'no newline' | IFS='' read -r
echo 'Did not make it here'

-3

Tôi nghĩ đó là cách duy nhất để có được một dòng mới ở cuối chuỗi ở đây - bằng chứng:

xxd <<<`echo -ne "a\n"`

Dường như toán tử chuỗi ở đây loại bỏ các dòng mới trừ khi chúng được đưa ra theo cú pháp bạn đã gửi.


4
Đó là sự thay thế lệnh đang tước bỏ dòng mới cuối cùng. Bạn có thể đơn giản hóa điều này để xxd <<<$(echo a).
Gilles 'SO- ngừng trở nên xấu xa'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.