เหตุใด echo จึงไม่สนับสนุน“ \ e” (escape) เมื่อใช้อาร์กิวเมนต์ -e ใน MacOSX


36

เมื่อฉันพยายามพิมพ์ข้อความสีโดยใช้ ANSI escape sequences ผ่านechoคำสั่งในตัวดูเหมือนว่า\eลำดับ escape ในสตริงที่ฉันให้นั้นถูกตีความตามตัวอักษรแทนที่จะเป็น "escape" ที่ควรจะเป็นตัวแทน สิ่งนี้จะเกิดขึ้นใน Snow Leopard - ตัวอย่างด้านล่างนี้ทำงานได้ตามที่ต้องการใน Leopard

เห็นได้ชัดว่าechoรองรับ-eสวิตช์เนื่องจากตีความอย่างถูกต้อง\nเมื่อใช้งาน:

~ $ 
~ $ echo "\n"
\n
~ $ echo -e "\n"


~ $ 

แต่เมื่อฉันพยายามใช้\eฉันจะได้รับสิ่งนี้:

~ $ echo -e "\e[34mCOLORS"
\e[34mCOLORS
~ $ 

อย่างที่ฉันพูดใน Leopard สิ่งที่กล่าวมาข้างต้นจะให้สตริง "COLORS" เป็นสี

ไม่มีใครรู้เหตุผลว่าทำไมนี่อาจเป็นการเปลี่ยนแปลงที่ตั้งใจ? วิธีแก้ปัญหาสำหรับการพิมพ์ ANSI escape sequences จาก Bash script บน Snow Leopard?

รุ่นเปลือก Bash บนเครื่อง Leopard ของฉันนั้น3.2.17(1)-releaseและ3.2.48(1)-releaseบนเครื่อง Snow Leopard ของฉัน


1
คำถามที่ขัดแย้งกับโพสต์ ในคำถามที่คุณอ้างถึง / bin / echo ในขณะที่โพสต์คุณใช้ echo โดยไม่มีพา ธ ซึ่งส่วนใหญ่แล้วจะเป็น builtin echo ของเชลล์ของคุณ
0x89

แน่นอน - ขอบคุณสำหรับการสังเกต ฉันแก้ไขคำถามเพื่อสะท้อนสิ่งนี้
hasseg

คำตอบ:


24

ฉันไม่สามารถบอกคุณได้ว่าทำไมมันถึงไม่สนับสนุนอาร์กิวเมนต์นั้น (คุณอาจต้องถามโปรแกรมเมอร์เกี่ยวกับเรื่องนี้) ฉันรู้เพียงว่าในกล่อง Linux ของฉันฉันได้รับสิ่งนี้:

$ /bin/echo --help
Usage: /bin/echo [SHORT-OPTION]... [STRING]...
  or:  /bin/echo LONG-OPTION
Echo the STRING(s) to standard output.

  -n             do not output the trailing newline
  -e             enable interpretation of backslash escapes
  -E             disable interpretation of backslash escapes (default)
      --help     display this help and exit
      --version  output version information and exit

If -e is in effect, the following sequences are recognized:
*emphasized text*
  \0NNN   the character whose ASCII code is NNN (octal)
  \\     backslash
  \a     alert (BEL)
  \b     backspace
  \c     produce no further output
  \f     form feed
  \n     new line
  \r     carriage return
  \t     horizontal tab
  \v     vertical tab

NOTE: your shell may have its own version of echo, which usually supersedes
the version described here.  Please refer to your shell's documentation
for details about the options it supports.

Report echo bugs to bug-coreutils@gnu.org
GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
General help using GNU software: <http://www.gnu.org/gethelp/>
Report echo translation bugs to <http://translationproject.org/team/>
  • สิ่งนี้ไม่ได้พูดถึงการ\eหลบหนี
  • มันบอกว่ามัน/bin/echoมาจาก gnu coreutils เมื่อแอปเปิ้ลเปลี่ยนแหล่งที่มาของส่วนประกอบของระบบยูนิกซ์เป็นครั้งคราว (เช่นย้ายจาก zsh เป็นทุบตี) ให้ตรวจสอบว่ามีการเปลี่ยนแปลง/bin/echoระหว่าง Leopard และ Snow Leopard หรือไม่ หากเป็น gnu คุณสามารถถามผู้คนได้ที่ gnu.org ทำไมพวกเขาเลือกที่จะไม่รวมลำดับเหล่านั้น

สำหรับวิธีแก้ปัญหา (นั่นน่าสนใจกว่า): ไม่ได้ใช้/bin/echoแต่ builtin ของ bash echoทำงานบนกล่อง linux หากพวกเขาเปลี่ยนเป็น bash โดยไม่มี builtin echo (หรือบางสิ่งที่คลุมเครือมากกว่า) คุณสามารถลองใช้คุณสมบัตินี้ที่ไม่รู้จักกันอย่างกว้างขวางในเชลล์ของคุณ (ทำงานอย่างน้อยใน bash และ zsh):

$ echo $'\e[34m''COLORS'

นี่คือส่วนที่ตรงกันของ manpage ของ bash:

   Words  of  the  form  $'string' are treated specially.  The word expands to string, with
   backslash-escaped characters replaced as specified by the ANSI  C  standard.   Backslash
   escape sequences, if present, are decoded as follows:
          \a     alert (bell)
          \b     backspace
          \e     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \'     single quote
          \nnn   the  eight-bit  character whose value is the octal value nnn (one to three
                 digits)
          \xHH   the eight-bit character whose value is the hexadecimal value  HH  (one  or
                 two hex digits)
          \cx    a control-x character

   The expanded result is single-quoted, as if the dollar sign had not been present.

   A  double-quoted string preceded by a dollar sign ($) will cause the string to be trans
   lated according to the current locale.  If the current locale is C or POSIX, the  dollar
   sign  is  ignored.  If the string is translated and replaced, the replacement is double-
   quoted.

4
ฉันไม่ทราบว่า$'string'จะเปิดใช้งาน escape sequence ได้หรือไม่ขอบคุณ
hasseg

1
\eไม่ได้เป็นส่วนหนึ่งของมาตรฐาน POSIX; การใช้งาน coreutils ของ GNU นั้นเพิ่มขึ้นตามมาตรฐาน OS X ทำไม่ได้
Martijn Pieters


15

ไม่\033ยังคงทำงาน? หากไม่มีคุณหวังว่าจะสามารถกด Ctrl + V แล้วตามด้วยปุ่ม Escape (หาก mac มีปุ่มเหล่านั้น) เพื่อสร้างตัวควบคุมจริงภายในบรรทัดคำสั่ง (ซึ่งใช้ไม่ได้ผลดีในสคริปต์ของหลักสูตรขึ้นอยู่กับบรรณาธิการ)


5
\033แทนที่จะ\eทำงานขอบคุณ
hasseg

4
เพียงเพื่ออ้างอิง33เป็นค่าฐานแปดของตัวหนี
TachyonVortex

สำหรับการอ้างอิงผู้อ่านในอนาคต033จะเป็นวิธีมาตรฐานในการเขียนเลขฐานแปด
ocodo

11

อีกวิธีหนึ่งในการพิมพ์ลำดับหนี ANSI /usr/bin/printfในเปลือกคือการใช้


3
printf เป็นวิธีพกพาในการแสดงสิ่งต่าง ๆ ในเปลือก มีมากเกินไปรสชาติของก้องจะ ...
mouviciel

6

ในการเติมเต็มคำตอบที่เป็นประโยชน์ที่มีอยู่ด้วยข้อมูลพื้นหลัง :

หากคุณกำลังกล่าวอ้างechoโดยชื่อเท่านั้น - เมื่อเทียบกับที่มีเส้นทางของมัน/bin/echo- คุณกำลังอัญเชิญทุบตีbuiltinมากกว่ายูทิลิตี้ภายนอก

พฤติกรรมขององค์ประกอบทุบตีดั้งเดิมเช่น builtins โดยทั่วไปจะสามารถพกพาได้ในความหมายของ Bash ซึ่งหมายความว่าพวกเขาควรทำงานแบบเดียวกันบนแพลตฟอร์มใด ๆ ที่สามารถใช้งาน Bashได้

\eเป็นข้อยกเว้นที่อยากรู้อยากเห็นที่มีผลต่อเวอร์ชัน 3.x Bash บน macOS (จนถึงทุกวันนี้ตั้งแต่ v10.13.5 (High Sierra), macOS มาพร้อมกับ Bash รุ่น 3.x ที่ล้าสมัยด้วยเหตุผลทางกฎหมาย)

\e(และนามแฝงของมัน\E) ควรทำงานกับecho -e; \eการสนับสนุนเพิ่มขึ้นechoในตัวในทุบตี 2.0 แต่อย่างลึกลับไม่ได้อยู่ในรุ่นสต็อก 3.x บน macOS

\e ไม่ทำงานในรุ่น 3.x ทุบตีในอื่น ๆแพลตฟอร์มเช่น MSYS บน Windows

ในทางกลับกันถ้าคุณติดตั้งและใช้ 4.x Bash บน macOS \e จะทำงานได้


2

พวกเขาอาจพยายามปฏิบัติตาม POSIX: http://www.opengroup.org/onlinepubs/9699919799/

ตัวเลือกส่วนระบุในสิ่งอื่น ๆ :

Implementations shall not support any options.

นี่คือลิงค์โดยตรงไปยังเนื้อหาที่ฉันคิดว่าคุณต้องการ: opengroup.org/onlinepubs/9699919799/utilities/echo.html
หยุดชั่วคราวจนกว่าจะมีประกาศเพิ่มเติม

Nope หน้ายังคงเขียน: 'ถ้าตัวถูกดำเนินการแรกคือ -n หรือถ้าตัวถูกดำเนินการตัวใดตัวหนึ่งมีอักขระ <backslash> ผลลัพธ์จะถูกกำหนดโดยการนำไปใช้' นอกจากนี้ macOS echo ก็ตีความ-eเช่นกัน
Yongwei Wu

2

FYI เรากำลังจะเพิ่มการสนับสนุน \ e ไปยัง / bin / echo และ / usr / bin / printf ใน coreutils หมายเหตุมาตรฐาน C ไม่ได้ระบุ \ e แต่ gcc, perl, bash, ksh และ tcsh สนับสนุน


0

คุณอาจตรวจสอบว่า ,, escape ตัวอักษรที่ไม่ใช่ ASCII '' ยังไม่ได้ตรวจสอบในเมนูตัวเลือกมุมมองของ terminal.app

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.