คุณยังสามารถใช้printf
คำสั่งแทน echo:
printf '%s\n' *
printf
จะดีกว่าecho
ในสถานการณ์เช่นนี้ในการที่echo
จะไม่เคารพ "ประคู่" ( --
) ที่มีความหมายท้ายของรายการอาร์กิวเมนต์ (ในบางระบบรวมทั้ง Ubuntu 14.04 ซึ่งเป็นสิ่งที่ผมทดสอบบน):
llama@llama:~$ mkdir -p Misc/unix210948
llama@llama:~$ cd !$
cd Misc/unix210948
llama@llama:~/Misc/unix210948$ touch -- -n
llama@llama:~/Misc/unix210948$ ls
-n
llama@llama:~/Misc/unix210948$ echo *
llama@llama:~/Misc/unix210948$ echo -- *
-- -n
llama@llama:~/Misc/unix210948$ printf '%s\n' *
-n
ในกรณีนี้คุณไม่สามารถบรรลุผลลัพธ์ที่ต้องการด้วยecho
(เนื่องจากไฟล์ที่เรียกว่า-n
ถูกตีความว่าเป็นตัวเลือกและเครื่องหมายขีดกลางไม่ทำงานดังนั้นคุณต้องใช้printf
)
โปรดทราบว่าคุณควรเสมอใช้รูปแบบของสตริงเหมือนข้างต้นเมื่อจัดการกับข้อมูลที่ไม่รู้จักด้วยprintf
เนื่องจากมิฉะนั้นคุณจะได้รับผลที่ไม่คาดคิด (ขอบคุณ @ G-Man สำหรับการชี้ออกมานี้ในความคิดเห็น!):
llama@llama:~/Misc/unix210948$ rm ./-n
llama@llama:~/Misc/unix210948$ touch '\n'
llama@llama:~/Misc/unix210948$ ls
\n
llama@llama:~/Misc/unix210948$ printf -- *
llama@llama:~/Misc/unix210948$ printf '%s\n' *
\n
ไฟล์ที่เรียกว่าถูกตีความว่าเป็นบรรทัดใหม่โดย\n
printf
เพื่อหลีกเลี่ยงปัญหานี้เราใช้สตริงการจัดรูปแบบสำหรับprintf
( %s
) และส่งชื่อของไฟล์ (ขยายผ่านการวนรอบตามเดิม)
printf
โซลูชันสตริงการจัดรูปแบบ + นี้สามารถจัดการชื่อไฟล์ที่หลากหลาย (และยังถือว่าไฟล์ "ซ่อน" ซึ่งก็คือไฟล์ที่ขึ้นต้นด้วย a .
เหมือนกับที่มีls
):
llama@llama:~/Misc/unix210948$ rm ./*
zsh: sure you want to delete all the files in /home/llama/Misc/unix210948/. [yn]? y
llama@llama:~/Misc/unix210948$ touch -- '-n' '\n' 'name with spaces' '.hidden'
llama@llama:~/Misc/unix210948$ ls
-n \n name with spaces
llama@llama:~/Misc/unix210948$ printf '%s\n' *
-n
\n
name with spaces
หากการprintf
สนับสนุนของ%q
คุณคุณสามารถใช้ ( printf '%q\n' *
) การทำเช่นนี้จะเป็นการเว้นวรรคบรรทัดใหม่ ฯลฯ หากมีอักขระแปลก ๆ ในชื่อไฟล์ของคุณ (ขอบคุณ@muru ในการแชทเพื่อชี้เรื่องนี้ !)
libc*so
หรือของคุณld-linux*so