ฉันเขียนสคริปต์ง่าย ๆ เมื่อฉันรันsh <myscriptname.sh>
ฉันได้รับเอาต์พุตที่ถูกต้อง แต่เมื่อฉันรัน./<myscriptname.sh>
ฉันพบข้อผิดพลาด
ความแตกต่างระหว่างตอนที่ผมทำคืออะไรsh
และ./
?
ฉันเขียนสคริปต์ง่าย ๆ เมื่อฉันรันsh <myscriptname.sh>
ฉันได้รับเอาต์พุตที่ถูกต้อง แต่เมื่อฉันรัน./<myscriptname.sh>
ฉันพบข้อผิดพลาด
ความแตกต่างระหว่างตอนที่ผมทำคืออะไรsh
และ./
?
คำตอบ:
เมื่อคุณเรียกใช้สคริปต์ใด ๆ โดยส่งชื่อไฟล์ไปยังโปรแกรมตัวแปลสคริปต์คุณกำลังเรียกใช้โปรแกรมตัวแปลโดยที่สคริปต์เป็นอาร์กิวเมนต์ที่ส่งผ่านเข้าไป เช่นนี้ดูเหมือนว่ากระบวนการ 'sh' กับอาร์กิวเมนต์ 'filename.sh' sh
ล่ามเปิดไฟล์
ในทางตรงกันข้ามถ้าคุณเรียกใช้สคริปต์ตัวเองระบบโทรออกไปยังโปรแกรมล่ามที่ระบุและฟีดในเนื้อหาสคริปต์ ในกรณีนี้กระบวนการดูเหมือนว่า 'filename.sh' โดยไม่มีข้อโต้แย้ง
คุณควรตรวจสอบให้แน่ใจว่าคุณมีสายปัง:
#!/bin/bash
# bash script here
บรรทัด bang เป็นบรรทัดแรกในสคริปต์และเริ่มต้นด้วยอักขระสองตัวเดียวกัน#!
นี่คือสิ่งที่ระบบอ่านเมื่อพยายามเรียกใช้สคริปต์จากนั้นระบบจะส่งสคริปต์ไปยังโปรแกรมทันทีหลังจากนั้น โปรดทราบว่าบรรทัดนี้ไม่มีอะไรเกี่ยวข้องกับการทุบตีและทำงานได้ดีกับงูหลามและ Perl แม้ว่ามันจะเป็นภาษาที่แตกต่างกันมากก็ตาม คุณจะใช้#!/usr/bin/python
เป็นตัวอย่างแล้วตามด้วยรหัสหลาม
เมื่อคุณมีสคริปต์ตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าการอนุญาตให้ใช้งานแล้ว:
chmod a+x filename.sh
จากนั้นคุณสามารถเรียกใช้สคริปต์เป็นกระบวนการของตัวเอง:
./filename.sh
หรือวางไฟล์ลงในตำแหน่งที่รู้จักพร้อมชื่อโปรแกรมที่ดีชอบ/usr/sbin
และเรียกใช้จากที่ใดก็ได้:
sudo cp filename.sh /usr/sbin/program-name
program-name
และนี้เป็นจริงในทางปฏิบัติประโยชน์ของการใช้สายปังที่มีสิทธิ์ - มันคือทั้งหมดที่เกี่ยวกับการใช้งาน เป็นการยากมากที่จะให้ผู้ใช้เรียกใช้สคริปต์หากพวกเขาต้องจำโปรแกรมที่เรียกใช้สคริปต์ด้วย อย่าลืมให้เส้นทางแบบเต็มไปยังสคริปต์ทุกครั้งที่ต้องการเรียกใช้ /usr/local/bin
ตัวอย่างเช่นเมื่อวางไว้ที่ใดและทำให้สามารถใช้งานได้สามารถบันทึกความเศร้าโศกมากมายสำหรับผู้ที่พยายามใช้สคริปต์ของคุณ โปรแกรมเหล่านี้จะพร้อมใช้งานสำหรับผู้ใช้ทุกคนในคอมพิวเตอร์ของคุณ
นอกจากนี้ยังเป็นสิ่งที่ดีสำหรับการระบุตัวตน ถ้าคุณเข้าไปในtop
โปรแกรมการทำงานสคริปต์ไม่มีสายปังก็จะมีชื่อของล่ามคือbash
, หรือperl
python
แต่ถ้าสคริปต์รันด้วยสิทธิ์ที่ถูกต้องชื่อของสคริปต์ก็จะปรากฏขึ้น
หมายเหตุ:หากคุณต้องการแจกจ่ายสคริปต์ที่ทุกคนสามารถเข้าถึงได้โปรดสร้าง man page และแพ็กเกจ deb เพื่อติดตั้ง เราจำเป็นต้องลดจำนวนสคริปต์สุ่มทางออนไลน์และเพิ่มจำนวนของเดบิตที่สามารถถอนการติดตั้งได้
bash
sh
PATH
อย่าใส่ส่วนขยายในสคริปต์โดยเฉพาะอย่างยิ่งเมื่อคุณไม่ได้ใส่ไว้ใน
/usr/local/bin
น่าจะดีกว่าแล้ว/usr/sbin
- มันบ่งบอกว่าโปรแกรมอยู่ภายในเครื่องนี้แทนที่จะเป็นส่วนหนึ่งของการกระจาย
รุ่นสั้น:
sh
เป็นล่ามบรรทัดคำสั่ง (เส้นประ)
การทำงานsh my_script
ทำให้ dash ตีความสคริปต์
./
พยายามค้นหาล่ามที่จะใช้โดยดูที่บรรทัดแรก เช่น#!/bin/bash
หรือแม้กระทั่ง#!/bin/ruby
(ตรงข้ามกับการทำงานruby my_script
)
./
ที่พบอะไรจริงๆมันเป็นวิธีการดำเนินการระบบซึ่งดูที่สองไบต์แรกของไฟล์
sh
และไฟล์มี sha-bang หมายความว่า sha-bang จะถูกเพิกเฉยหรือมันจะเปิดเชลล์ที่sh
ลิงก์ด้วยเช่นกันและบางทีเชลล์อื่น ๆ หรือมันทำอะไร :)?
ความแตกต่างที่คุณทำคือ
ด้วยsh
, คุณกำลังเรียกใช้โปรแกรมที่จะตีความบรรทัดในสคริปต์ของคุณเหมือนกับที่คุณพิมพ์บนพรอมต์แบบโต้ตอบของเทอร์มินัล
เมื่อ./
คุณใช้ช็อตคัทสมมติว่าสคริปต์อยู่ตรงนี้ในไดเรกทอรีปัจจุบันที่คุณใช้งานและมันจะสามารถเรียกใช้งานได้ (เพราะเช่นคุณออกใช้chmod +x myscript.sh
) ช่วยให้คุณประหยัดเวลาอันมีค่าสำหรับเวลาในอนาคต :-)
sh
ไฟล์จะต้องไม่สามารถเรียกใช้งานได้
มีสามเหตุผลหลักที่คุณอาจได้รับข้อผิดพลาด:
chmod +x <myscriptname.sh>
เพื่อปฏิบัติการได้noexec
") /usr/local/bin
#!
บรรทัดมีข้อผิดพลาด#!/bin/sh
หรือ#!/bin/bash
หากบรรทัดแรกของคุณดูถูกต้อง แต่ก็ยังใช้งานไม่ได้ตรวจสอบให้แน่ใจว่าไฟล์นั้นไม่มีจุดสิ้นสุดของบรรทัด DOS
ข้อผิดพลาดจะมีลักษณะดังนี้:
$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory
คุณสามารถแก้ไขได้โดยการทำงานหรือถ้าคุณไม่ได้ว่าdos2unix <myscriptname.sh>
perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>
และคำตอบก็คือ sh คือชื่อของเปลือกหอยยอดนิยม แต่ล้าสมัยและถูกแทนที่โดยผู้อื่น ทุกวันนี้ SH เชื่อมโยงกับเชลล์อื่น ๆ ที่ติดตั้งบนเครื่อง เช่นฉันทุบตีที่นั่น การเรียกใช้เชลล์ใด ๆ จาก sh มักจะเรียกใช้โหมด 'ความเข้ากันได้' บางอย่างกับพฤติกรรมของ 'เชลล์' ดั้งเดิม
ดังนั้นการแก้ปัญหาค่อนข้างง่าย ดูว่ามีอะไรอยู่เบื้องหลังคำสั่ง sh (ls -al / bin / sh) และใส่ #! / bin / Anything_you_find_there เป็นบรรทัดแรก (หรือหากมีบางอย่างในสคริปต์ของคุณแก้ไขมัน)
และอาจมีข้อผิดพลาดบางอย่างในสคริปต์ของตัวเอง เช่นเดียวกับการพึ่งพาที่พบโดย sh แต่ไม่ใช่ล่ามที่ใช้จริง
mkdir ~/bin ; cp myscript.sh ~/bin/
echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ;
ไม่ใช่/usr/sbin
สำหรับเครื่องมือการดูแลระบบที่ไม่จำเป็น/usr/local/bin
เป็นตัวเลือกที่ดีกว่าถ้าคุณไม่ต้องการมี~/bin/
แต่แนะนำให้หลีกเลี่ยงsudo
มากที่สุด
~/.profile
แล้วมีรหัสสำหรับการเพิ่มถ้ามันมีอยู่แล้วที่จะ~/bin
PATH
ในบันทึกอื่นอย่าใส่ส่วนขยายลงในสคริปต์
ls ~/bin/|wc -l = 428
) ฉันใส่ของจำนวนมากลงในนั้น;)
/bin
และ/usr/bin
คุณจะเห็นพวกเขาไม่ได้ใช้ส่วนขยาย