เหตุใดข้อความแสดงข้อผิดพลาดสำหรับสองโคลอนเป็นคำสั่ง (: :) ใน bash มีสามโคลอน แต่โคลอนเดียวไม่แสดงผลลัพธ์


27

ถ้าฉันพิมพ์

::

ฉันได้รับ:

-bash: ::: command not found

แต่มีเพียง:ผลลัพธ์เดียวเท่านั้นที่ไม่มีเอาต์พุต ทำไมนี้


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
โธมัสวอร์ด

สิ่งนี้เกี่ยวข้องกับ Ubuntu อย่างไร
NerdOfCode

@NerdOfCode ในลักษณะเดียวกันนี้คืออะไร? meta.askubuntu.com/q/17076/158442
muru

คำตอบ:


40

:เปลือกในตัวเทียบกับที่ไม่มีอยู่จริง::

: เปลือกในตัวคำสั่งที่มีอยู่ (หมายเหตุความแตกต่างระหว่างภายนอกและในตัวคำสั่ง ) ซึ่งไม่ได้ทำอะไร; มันแค่คืนความสำเร็จเช่นเดียวกับtrueคำสั่ง :ในตัวเป็นมาตรฐานที่กำหนดโดยมาตรฐาน POSIXที่เป็นที่รู้จักกันว่า "ยูทิลิตี้ null" มันมักใช้สำหรับการทดสอบหรือสำหรับการวนซ้ำไม่สิ้นสุดเช่นเดียวกับในwhile : ; do ...;done

bash-4.3$ type :
: is a shell builtin

อย่างไรก็ตาม::- อักขระโคลอนสองตัวพร้อมกัน - ถูกตีความว่าเป็น "หนึ่งคำ" ต่อเชลล์และถือว่าเป็นคำสั่งที่ผู้ใช้ป้อน เชลล์จะผ่านกระบวนการตรวจสอบบิวด์อินจากนั้นไดเร็กทอรีใด ๆ ในPATHตัวแปรสำหรับการมีอยู่ของคำสั่งนั้น แต่มีค่าในตัวหรือคำสั่งภายนอก:: ::ดังนั้นนั่นทำให้เกิดข้อผิดพลาด

รูปแบบทั่วไปสำหรับข้อผิดพลาดคืออะไร

<shell>: <command user typed>: error message

ดังนั้นสิ่งที่คุณเห็นไม่ใช่ 3 โคลอน แต่สิ่งที่คุณพิมพ์ลงในรูปแบบข้อผิดพลาดมาตรฐาน

โปรดสังเกตว่า:สามารถรับอาร์กิวเมนต์บรรทัดคำสั่งได้เช่นกัน:

: :

ในกรณีนี้เชลล์จะพิจารณาว่าเป็น "สองคำ" ซึ่งหนึ่งในนั้นคือคำสั่งและอีกหนึ่งพารามิเตอร์ตำแหน่ง นั่นจะทำให้ไม่มีข้อผิดพลาด! (โปรดดูบันทึกย่อเชิงประวัติ (คำตอบนี้ในภายหลัง) เกี่ยวกับการใช้:ด้วยพารามิเตอร์ตำแหน่ง)


ในหอยอื่นที่ไม่ใช่ bash

โปรดทราบว่าการจัดรูปแบบอาจแตกต่างกันระหว่างเชลล์ที่แตกต่างกันเช่นกัน สำหรับbash, kshและmkshพฤติกรรมที่สอดคล้องกัน ตัวอย่างเช่น/bin/shเชลล์เริ่มต้นของ Ubuntu (ซึ่งจริงๆแล้ว/bin/dash):

$ dash
$ ::
dash: 1: ::: not found

โดยที่ 1 คือหมายเลขคำสั่ง (เทียบเท่ากับหมายเลขบรรทัดในสคริปต์)

csh ในทางตรงกันข้ามจะไม่มีข้อความแสดงข้อผิดพลาดเลย:

$ csh
% ::
%

ในความเป็นจริงหากคุณรันstrace -o csh.trace csh -c ::เอาต์พุตการติดตามในcsh.traceไฟล์จะแสดงว่าcshออกจากสถานะออก 0 (ไม่มีข้อผิดพลาด) แต่tcshจะส่งออกข้อผิดพลาด (โดยไม่ต้องแสดงชื่อของมัน):

$ tcsh
localhost:~> ::
::: Command not found.

ข้อความผิดพลาด

โดยทั่วไปรายการแรกในข้อความแสดงข้อผิดพลาดควรเป็นกระบวนการดำเนินการหรือฟังก์ชั่น (เชลล์ของคุณพยายามดำเนินการ::ดังนั้นข้อความแสดงข้อผิดพลาดมาจากเชลล์) ตัวอย่างเช่นที่นี่กระบวนการดำเนินการคือstat:

$ stat noexist
stat: cannot stat 'noexist': No such file or directory

ในความเป็นจริง POSIX กำหนดฟังก์ชั่นperror ()ซึ่งตามเอกสารประกอบการใช้อาร์กิวเมนต์สตริงแล้วส่งออกข้อความข้อผิดพลาดหลังจากลำไส้ใหญ่แล้วขึ้นบรรทัดใหม่ อ้างถึง:

ฟังก์ชัน perror () จะแมปหมายเลขข้อผิดพลาดที่เข้าถึงได้ผ่านสัญลักษณ์ errno กับข้อความแสดงข้อผิดพลาดที่ขึ้นกับภาษาซึ่งจะถูกเขียนลงในสตรีมข้อผิดพลาดมาตรฐานดังต่อไปนี้:

  • ครั้งแรก (ถ้า s ไม่ได้เป็นตัวชี้โมฆะและตัวละครที่ชี้ไปโดย s ไม่ใช่ไบต์ว่าง) สตริงที่ชี้ไปตาม s ตามด้วยเครื่องหมายจุดคู่และ <space>

  • จากนั้นสตริงข้อความข้อผิดพลาดตามด้วย <newline>

และอาร์กิวเมนต์สตริงperror()ในทางเทคนิคจะเป็นอะไร argv[0]แต่แน่นอนเพื่อความชัดเจนก็มักชื่อฟังก์ชันหรือ

ในทางตรงกันข้าม GNU มีชุดฟังก์ชั่นและตัวแปรของตัวเองสำหรับการจัดการข้อผิดพลาดซึ่งโปรแกรมเมอร์สามารถใช้fprintf()เพื่อstderrสตรีม เป็นหนึ่งในตัวอย่างในหน้าที่เชื่อมโยงแสดงสิ่งนี้สามารถทำได้:

  fprintf (stderr, "%s: Couldn't open file %s; %s\n",
           program_invocation_short_name, name, strerror (errno));

บันทึกประวัติศาสตร์

ในเชลล์ Unix และ Thompson เก่า:ถูกใช้กับgotoคำสั่ง (ซึ่งตามผู้ใช้ชื่อ Perderabo ในเธรดนี้ไม่ใช่เชลล์ในตัว) อ้างจากคู่มือ:

ไฟล์คำสั่งทั้งหมดถูกค้นหาบรรทัดที่ขึ้นต้นด้วย: เป็นอักขระแรกที่ไม่ใช่ช่องว่างตามด้วยช่องว่างหนึ่งช่องหรือมากกว่าจากนั้นตามด้วยเลเบล หากพบบรรทัดดังกล่าว goto จะเปลี่ยนตำแหน่งคำสั่งไฟล์ออฟเซ็ตเป็นบรรทัดหลังจากเลเบลและออก สิ่งนี้ทำให้เชลล์ถ่ายโอนไปยังบรรทัดที่มีเลเบล

ดังนั้นคุณสามารถทำสิ่งนี้เพื่อสร้างสคริปต์ลูปไม่สิ้นสุด:

: repeat
echo "Hello World"
goto repeat

"3 คอลัมน์" ตัวพิมพ์ใหญ่สำหรับ "3 colons"
Barmar

1
DOS command.comและ Windows ' cmd.exeมีสถานการณ์ที่คล้ายกัน แต่ตรงกันข้าม: :เป็นป้ายชื่อ goto (ไม่ใช่คำสั่ง) และมักจะนำมาใช้ใหม่เป็นอักขระแสดงความคิดเห็น (เช่น:: This is a comment)
grawity

54

เครื่องหมายโคลอนสุดท้ายเป็นเพียงส่วนหนึ่งของข้อความ "ไม่พบ" ที่เป็นค่าเริ่มต้น:

$ x
x: command not found
$ ::
::: command not found

เหตุผลที่โคลอนเดียวสร้างไม่มีอะไรนั่น: คือคำสั่งที่ถูกต้อง - แม้ว่าจะไม่ทำอะไรเลย (ยกเว้นการส่งคืนTRUE) จากSHELL BUILTIN COMMANDSส่วนของman bash:

   : [arguments]
          No effect; the command does nothing beyond  expanding  arguments
          and  performing any specified redirections.  A zero exit code is
          returned.

บางครั้งคุณจะเห็นมันในสิ่งปลูกสร้างเช่น

while :
do
  something
done

ดูตัวอย่างจุดประสงค์ของลำไส้ใหญ่ที่มีอยู่ภายในทำหน้าที่อะไร


ใช่นี่คือความคิดเห็นที่ครอบคลุมมากที่สุด .. มีคารมคมคายมากกว่าของฉัน .. อธิบายได้ดีกว่ามาก: D
John Orion

8

ลองใช้คำสั่งที่ไม่มีอยู่จริงอื่น ๆ แล้วคุณจะเห็นว่า:วัตถุประสงค์ดังกล่าวเป็นภาษาอังกฤษตามปกติ:

$ ---
---: command not found

6

เครื่องหมายโคลอนที่เพิ่มเป็นส่วนหนึ่งของข้อความแสดงข้อผิดพลาด หากcd owมีผลลัพธ์ประเภทหนึ่งbash: cd: ow: No such file or directoryแสดงว่ามีข้อผิดพลาดเกิดขึ้นในเครื่องหมายโคลอนพิเศษ: No such file or directory


6
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found

ที่สามเป็นตัวเว้นวรรคจากการจัดรูปแบบ

ใน bash a :เป็นโมฆะบรรทัดว่างเปล่า


4

คุณได้รับ 3 colons เนื่องจากรูปแบบข้อผิดพลาดประกอบด้วยโคลอน:

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