Làm cách nào để in '-e' với tiếng vang?


8

Tôi biết đó echo -ekhông phải là một mệnh lệnh thông thường. Tôi đã thử echo '-e'echo \-ehọ vẫn không làm việc.


1
Bạn có ý nghĩa gì với 'không phải là một dòng lệnh thông thường'? echothường là một vỏ dựng sẵn, nhưng thường cũng có /usr/bin/echo. Đây -ekhông phải là POSIX, nhưng có sẵn, ví dụ như với bash. Vui lòng cung cấp thêm chi tiết về ý nghĩa của bạn với 'chúng vẫn không hoạt động'. Hành vi dự kiến ​​là gì?
maxschlepzig

Tôi muốn in -e bằng echo. Bất kỳ đề xuất?
Nhà máy nổi bật

3
xem xét sử dụng printf, nó dễ mang theo hơn.
Michael Durrant

1
Thật kỳ lạ, echo -- -ecũng không hoạt động. Thông thường (với các tiện ích GNU ít nhất) dấu gạch ngang kép biểu thị kết thúc của các tùy chọn, phần còn lại được giữ dưới dạng đối số theo nghĩa đen.
Wil Cooley

6
echolại điên lên. Nếu mọi người sẽ chỉ sử dụng printfvà không bao giờ nhìn lại.
Jens

Câu trả lời:


9
  • với dòng mới

    echo -en '-e\n'
  • không có dòng mới

    echo -e '-e\c'
  • với không gian xung quanh:

    echo '-e '
    echo ' -e'
  • sử dụng backspace (nhờ Joseph R.):

    echo -e ' \b-e'

    (nó xuất SPC BS - e LF, nhưng khi được gửi đến một thiết bị đầu cuối được hiển thị -ekhi BS di chuyển con trỏ trở lại một cột sang bên trái gây ra -ghi đè SPC)

Hành vi của bash's echoBUILTIN thể phụ thuộc vào phiên bản bash. Nó cũng phụ thuộc vào môi trường ( POSIXLY_CORRECT, SHELLOPTSBASHOPTSbiến), các tùy chọn ( posix, xpg_echo), các tùy chọn xây dựng và argv[0]( shvs bash). Ở đây đã thử nghiệm với GNU bash 4.2.53(1), bản dựng mặc định, tùy chọn mặc định, môi trường trống, được gọi là bash. Hoạt động cũng với zsh 5.0.5.


+1 Ngoài raecho -e 'x\b-e'
Joseph R.

2
Tại sao những "cách giải quyết" xấu xí này lại nhận được sự ủng hộ? Charles Duffy dưới đây có câu trả lời thích hợp: sử dụng printf và quên đi những vấn đề như vậy một lần và mãi mãi.
Jens

7
Jens: bởi vì OP đã hỏi cách thực hiện với echolệnh. Thái độ không cần thiết.
ctc

1
echo -e ' \b-e'đầu ra không gian-backspace-dash-e. Chỉ hiển thị trong một thiết bị đầu cuối, nó sẽ cho bạn ảo tưởng rằng nó là dash-e.
Stéphane Chazelas

1
@CharlesDuffy, echo -e "\0-e"không xuất NUL-dash-e. Nó chỉ là thiết bị đầu cuối bỏ qua mà nhân vật NUL (NUL thậm chí sử dụng để được gửi đến một số thiết bị đầu cuối (không hỗ trợ kiểm soát dòng chảy) để cung cấp cho họ thời gian để làm những việc dài khác giống như một vận chuyển trở lại. Xem phần dưới chậm trễ và Padding trong terminfo(5).)
Stéphane Chazelas

25

Giải pháp tốt nhất không phải là sử dụng echo, mà là sử dụng printfthay thế.

printf '%s\n' -e

Điều này hoạt động với các biến tùy ý:

var=-e
printf '%s\n' "$var"

... có nghĩa là bạn không cần thực hiện bất kỳ sự chuẩn bị / sửa đổi đặc biệt nào khác trong mã của mình dựa trên kiến ​​thức rằng giá trị sẽ là echod.


Ngẫu nhiên, đặc tả lệnh shell POSIX đểecho xác nhận rằng nó không thể truy cập được khi được triển khai và có một ghi chú về chủ đề đó:

Không thể sử dụng echo có thể di chuyển trên tất cả các hệ thống POSIX trừ khi cả hai -n (như đối số đầu tiên) và các chuỗi thoát được bỏ qua.

Tiện ích printf có thể được sử dụng một cách hợp lý để mô phỏng bất kỳ hành vi truyền thống nào của tiện ích echo như sau (giả sử rằng IFS có giá trị tiêu chuẩn hoặc không được đặt):

Tiếng vang của Hệ thống V lịch sử và các yêu cầu đối với việc triển khai XSI trong tập POSIX.1-2008 này tương đương với:

printf "%b\n" "$*"

Tiếng vang BSD tương đương với:

if [ "X$1" = "X-n" ]
then
    shift
    printf "%s" "$*"
else
    printf "%s\n" "$*"
fi

Các ứng dụng mới được khuyến khích sử dụng printf thay vì echo.

(Nhấn mạnh thêm).


Điều đó nói rằng, trên các hệ thống GNU, tồn tại một giải pháp thay thế: Yêu cầu hành vi tuân thủ tiêu chuẩn.

$ POSIXLY_CORRECT=1 /bin/echo -e
-e

Thật thú vị, ghi chú POSIX nói rằng đó echo -elà hàng xách tay. Nó nói -nphải được tránh, và các chuỗi thoát phải được tránh. echo -etránh cả hai Nhưng như bạn chỉ ra trong phần cuối câu trả lời của mình, trên các hệ thống GNU, echokhông bận tâm tuân thủ POSIX theo mặc định và POSIX chỉ lưu ý tính di động trên các hệ thống POSIX.
hvd

@hvd, tôi không thấy -eđược bao phủ trong phần thông số kỹ thuật mà tôi liên kết đến. Bạn có thể cung cấp một liên kết hoặc trích dẫn bao gồm nó?
Charles Duffy

Đó là thiếu một đề cập nói rằng nó. :) Nó liệt kê các cách sử dụng không di động và -ekhông được đề cập, do đó -elà di động (một lần nữa, trên các hệ thống POSIX). Công bằng mà nói, những gì bạn trích dẫn là thông tin, nhưng văn bản quy phạm cũng nói điều tương tự: "Nếu toán hạng đầu tiên là -n hoặc nếu bất kỳ toán hạng nào chứa ký tự <backslash>, thì kết quả được xác định theo thực hiện."
hvd

2
@hvd, đúng hơn là ngược lại. Để thực hiện như được chỉ định, echocần phải phát ra tất cả các đối số không có hành vi được xác định theo cách trái ngược với tiêu chuẩn. Do đó - không giống như hầu hết tất cả các công cụ dòng lệnh khác được bao phủ bởi thông số POSIX - echothực sự chỉ định hành vi cho các đối số không được đưa ra: In chúng. Không có chỗ để thêm cờ mới mà không phá vỡ đặc điểm kỹ thuật.
Charles Duffy

2
@hvd, ... về vấn đề đó, hãy xem OPTIONSphần, nơi nó được đặt ra trong màu đen và trắng : Implementations shall not support any options.
Charles Duffy

9

Với GNU echo's -evới các mã ASCII cho các nhân vật:

$ /bin/echo -e '\055'e
-e

055là số ASCII bát phân cho -(xem man asciiđể tham khảo nhanh).


1
/bin/echothực sự là POSIX-chỉ định. Tuy nhiên, việc giải thích các chuỗi thoát bát phân của nó là một phần mở rộng XSI cho đặc tả cơ sở.
Charles Duffy

@CharlesDuffy Thật vậy, tôi sai chính tả. +1 cho printf (suy nghĩ đầu tiên của tôi là tốt). -eTuy nhiên, đó là một phần mở rộng, có cách nào để buộc hành vi POSIX thuần túy echokhông? Điều đó sẽ loại bỏ tất cả sự không chắc chắn về điều này, tôi nghĩ.
muru

2
Thật ra, vâng! Xuất khẩu POSIXLY_CORRECT=1sẽ dẫn đến hành vi tuân thủ POSIX cho GNU /bin/echo.
Charles Duffy

+1 Cảm ơn, nên biết để giữ cho các tập lệnh của bạn luôn di động và "độc lập với homebrew-Linux" (tức là cũng hoạt động trên máy trạm chuyên nghiệp tại nơi làm việc).
cú pháp

@Kusalananda quên mất điều này.
muru

3

Mặc dù giải pháp rõ ràng, tiêu chuẩn và được khuyến nghị là sử dụng printf, để thực hiện nó echocó thể khá khó khăn tùy thuộc vào việc thực hiện (không khó như -nmặc dù).

POSIX.2017 compliant echos

POSIX yêu cầu echo -e đầu ra -e<newline>. Vì vậy, nó chỉ

echo -e

ở đó Các tuân thủ POSIX echoliên quan đến vấn đề đó (hầu hết trong số chúng không tuân thủ POSIX về các khía cạnh khác, thông số POSIX gần như vô dụng khi nói đến echo) bao gồm:

  • các echoBUILTIN của bashkhi cả xpg_echoposixtùy chọn đã được kích hoạt (trong thời gian chạy hoặc thời gian xây dựng như cho /bin/shcủa Apple MacOS). set -o posix; shopt -s xpg_echo( posixtùy chọn cũng có thể được bật nếu được gọi là shhoặc khi POSIXLY_CORRECThoặc SHELLOPTS=posixtrong môi trường).
  • các /bin/echohệ thống UNIX được chứng nhận (ít nhất là AIX, macOS, Solaris) và hầu hết các BSD
  • các echoBUILTIN của dash, ksh88, Bourne shell, csh, tcsh, sang trọng, rc, es, akanga
  • GNU echo( /bin/echotrên các hệ thống GNU) khi POSIXLY_CORRECTở trong môi trường.
  • các echoBUILTIN của mkshvà một số pdksh-Xuất phát khác khi họ posixlựa chọn được kích hoạt.
  • các echoBUILTIN của yashkhi$ECHO_STYLE là một trong hai unset hoặc một trong SYSV, XSI, BSD, DASH,RAW

triển khai hỗ trợ -e

Bao gồm echocác nghiên cứu Unix V8 (nơi nó xuất phát từ), GNU, busybox, các echoBUILTIN của bash, zsh, pdkshvà các dẫn xuất, fishmột số ashvỏ dựa trên như busybox shhoặc shcủa một số BSDs, các phiên bản gần đây của ksh93(trên một số hệ thống, và với một số giá trị của $PATH) với cài đặt mặc định của họ, yashvới$ECHO_STYLE một trong GNUhoặc ZSH:

echo -e '-e\n\c'

Việc triển khai hỗ trợ -e luôn luôn hỗ trợ -n, vì vậy:

echo -ne '-e\n'

cũng sẽ làm việc

zsh

zshĐây echolà triển khai duy nhất mà tôi biết hỗ trợ điểm đánh dấu kết thúc tùy chọn ( -).

echo - -e

Làm cho nó trở thành vỏ giống như Bourne echo có thể xuất dữ liệu tùy ý (cũng bởi vì nó là lớp duy nhất hỗ trợ các byte NUL trong các biến của nó và các đối số của phần tử dựng sẵn) với echo -E - "$data")

Ngoại trừ vấn đề NUL byte, các triển khai khác có thể xuất dữ liệu tùy ý là FreeBSD hoặc macOS /bin/echonơi bạn có thể thực hiện:

/bin/echo "$data
\c"

(trong quá trình thực hiện đó, \cchỉ được nhận ra ở cuối và không có chuỗi thoát nào khác được hỗ trợ).

yash:

ECHO_STYLE=RAW echo "$data"

(mặc dù lưu ý rằng yashcác biến chỉ có thể giữ văn bản, chuỗi byte, vì thế không tùy ý trong miền địa phương nơi không phải tất cả các chuỗi byte có thể hình thành ký tự hợp lệ như thế nào trong những người sử dụng UTF-8 như charmap của họ).


2

Sử dụng -nđể tránh dòng mới:

$ echo -n - && echo e
-e

Điều đó sẽ không hoạt động ở zshđâu -là sự kết thúc của dấu phân cách tùy chọn hoặc trên tất cả các echotriển khai không hỗ trợ -n(những hỗ trợ -ecũng hỗ trợ -n)
Stéphane Chazelas 19/2/19
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.