คำถามติดแท็ก shell-script

คำถามเกี่ยวกับเชลล์สคริปต์ไฟล์เรียกทำงานที่ตีความโดยเชลล์ (bash, zsh ฯลฯ )

2
การเขียนสคริปต์เชลล์: ตัวเลือก -z และ -n ด้วย if
ฉันมีเชลล์สคริปต์ที่เรามีบรรทัดต่อไปนี้if [ -z "$xyz" ]และif [ -n "$abc" ]แต่ฉันไม่แน่ใจว่าจุดประสงค์ของพวกเขาคืออะไร ใครช่วยอธิบายหน่อยได้ไหม

14
วิธีที่ง่ายที่สุดในการค้นหาพอร์ตในเครื่องที่ไม่ได้ใช้คืออะไร
วิธีที่ง่ายที่สุดในการค้นหาพอร์ตในเครื่องที่ไม่ได้ใช้คืออะไร ขณะนี้ฉันกำลังใช้บางสิ่งที่คล้ายกับสิ่งนี้: port=$RANDOM quit=0 while [ "$quit" -ne 1 ]; do netstat -a | grep $port >> /dev/null if [ $? -gt 0 ]; then quit=1 else port=`expr $port + 1` fi done รู้สึกถึงวงเวียนอย่างสุดขีดดังนั้นฉันจึงสงสัยว่าจะมีเส้นทางที่ง่ายขึ้นเช่นตัวในที่ฉันพลาดไปหรือเปล่า

4
ดำเนินการคำสั่งก่อนปิดเครื่อง
ฉันต้องการรันคำสั่งง่าย ๆ ก่อนที่คอมพิวเตอร์จะปิดเครื่อง (การกำหนดเวลาไม่จำเป็น) สำหรับการเริ่มต้นฉันสามารถใช้ / etc / rc.local; มีบางอย่างที่คล้ายกันสำหรับการปิดระบบ? โปรดทราบว่าฉันยังต้องการใช้ปุ่มปิดการทำงานแบบรวมจากเมนู เช่นฉันไม่ต้องการใช้สคริปต์ที่กำหนดเองทุกครั้งที่ฉันปิดระบบผ่านเทอร์มินัล - มันต้องเป็นแบบอัตโนมัติ

5
การพิจารณาว่าไฟล์เป็นฮาร์ดลิงก์หรือลิงก์สัญลักษณ์?
ฉันกำลังสร้างเชลล์สคริปต์ที่จะนำชื่อไฟล์ / พา ธ ไปยังไฟล์และตรวจสอบว่าไฟล์นั้นเป็นลิงก์สัญลักษณ์หรือฮาร์ดลิงก์ สิ่งเดียวคือฉันไม่ทราบวิธีการดูว่าพวกเขาเป็นลิงค์ยาก ฉันสร้างไฟล์ 2 ไฟล์หนึ่งไฟล์เป็นฮาร์ดลิงก์และอีกหนึ่งลิงก์สัญลักษณ์เพื่อใช้เป็นไฟล์ทดสอบ แต่ฉันจะทราบได้อย่างไรว่าไฟล์เป็นฮาร์ดลิงก์หรือสัญลักษณ์ภายในเชลล์สคริปต์ นอกจากนี้ฉันจะค้นหาพาร์ติชันปลายทางของลิงก์สัญลักษณ์ได้อย่างไร สมมุติว่าฉันมีไฟล์ที่เชื่อมโยงไปยังพาร์ติชันอื่นฉันจะค้นหาพา ธ ไปยังไฟล์ต้นฉบับนั้นได้อย่างไร

4
ฉันควรจะดูแลแมวที่ไม่จำเป็นหรือไม่?
ยูทิลิตีบรรทัดคำสั่งจำนวนมากสามารถรับอินพุตได้จากไพพ์หรือเป็นอาร์กิวเมนต์ชื่อไฟล์ สำหรับเชลล์สคริปต์แบบยาวฉันพบว่าการเริ่มต้นลูกโซ่ด้วย a catทำให้อ่านได้ง่ายขึ้นโดยเฉพาะถ้าคำสั่งแรกต้องการอาร์กิวเมนต์หลายบรรทัด เปรียบเทียบ sed s/bla/blaha/ data \ | grep blah \ | grep -n babla และ cat data \ | sed s/bla/blaha/ \ | grep blah \ | grep -n babla วิธีหลังมีประสิทธิภาพน้อยลงหรือไม่ ถ้าเป็นเช่นนั้นความแตกต่างมากพอที่จะใส่ใจว่าสคริปต์รันหรือไม่พูดเป็นวินาทีหรือไม่ ความแตกต่างในการอ่านไม่มาก

5
ฉันจะออกจากสคริปต์ในคำสั่งแบบมีเงื่อนไขได้อย่างไร
ฉันกำลังเขียนสคริปต์ทุบตีที่ฉันต้องการออกหากผู้ใช้ไม่ได้รูท เงื่อนไขทำงานได้ดี แต่สคริปต์ไม่ออก [[ `id -u` == 0 ]] || (echo "Must be root to run script"; exit) ฉันลองใช้&&แทนที่จะใช้;แต่ไม่ได้ผล

1
อะไรคือความแตกต่างระหว่างเครื่องหมายคำพูด“ …”, '…', $ '…' และ $“ …”?
บางครั้งผมเห็นสคริปต์ใช้ทั้งหมดของวิธีการที่แตกต่างกันเหล่านี้อ้างข้อความบางส่วน: "...", '...', และ$'...' $"..."เหตุใดจึงมีการใช้เครื่องหมายคำพูดต่าง ๆ มากมาย? พวกเขามีพฤติกรรมที่แตกต่างหรือส่งผลกระทบต่อสิ่งที่ฉันสามารถทำได้ภายในพวกเขา?

4
ฉันจะลบองค์ประกอบออกจากอาร์เรย์ได้อย่างไร
unset array[0]เอาองค์ประกอบ แต่ถ้าฉันจะecho ${array[0]}ได้รับค่า Null นอกจากนี้ยังมีวิธีอื่นในการทำเช่นนี้ แต่ถ้าองค์ประกอบของอาร์เรย์มีช่องว่างเช่นด้านล่าง array[0]='james young' array[1]='mary' array[2]='randy orton' แต่สิ่งเหล่านี้ก็ไม่สามารถทำงานได้เช่นกัน array=${array[@]:1} #removed the 1st element ตอนนี้ฉันต้องการอาร์เรย์ใหม่ให้เป็นเหมือน array[0]='mary' array[1]='randy orton' ช่องว่างทำให้เกิดปัญหาหลังจากการกำหนดและอาร์เรย์ที่แท้จริงกลายเป็นเหมือนการทดแทน array=(mary randy orton)

2
ระงับข้อความ stderr ในสคริปต์ทุบตี
พิจารณาชื่อสคริปต์ต่อไปนี้ (โง่เล็กน้อย) 'test1.sh': #/bin/bash # sleep 10 & echo sleep pid = $! pkill sleep เมื่อฉันเรียกใช้ฉันไม่เพียง แต่เอาท์พุทของเสียงก้องเท่านั้น แต่ยังรายงานการตายของการนอนหลับบน stderr ด้วย: $ ./test1.sh sleep pid = 3551 ./test1.sh: line 5: 3551 Terminated sleep 10 ในกรณีนี้ฉันต้องการระงับการพิมพ์ไปยัง stderr ฉันรู้ว่าฉันสามารถทำได้ในบรรทัดคำสั่งเช่นเดียวกับใน: $ ./test1.sh 2> /dev/null ... แต่มีวิธีที่จะระงับมันจากภายในสคริปต์หรือไม่ (ฉันรู้ว่าฉันสามารถตัดมันในสคริปต์ที่สองและให้ wrapper เปลี่ยนเส้นทาง แต่ต้องมีบางสิ่งที่ง่ายกว่า ... )

4
ทุบตีแตกต่างระหว่างการขยายรั้งและการจัดกลุ่มคำสั่งได้อย่างไร
ฉันสังเกตเห็นว่า{สามารถใช้ในการขยายรั้ง: echo {1..8} หรือในการจัดกลุ่มคำสั่ง: {ls;echo hi} ทุบตีรู้ความแตกต่างได้อย่างไร?

4
ทำไม (ทางออก 1) ไม่ออกจากสคริปต์
ฉันมีสคริปต์ที่ไม่ได้ออกเมื่อฉันต้องการมัน ตัวอย่างสคริปต์ที่มีข้อผิดพลาดเดียวกันคือ: #!/bin/bash function bla() { return 1 } bla || ( echo '1' ; exit 1 ) echo '2' ฉันคิดว่าจะเห็นผลลัพธ์: :~$ ./test.sh 1 :~$ แต่ฉันเห็นจริง: :~$ ./test.sh 1 2 :~$ ที่ไม่()สั่งการผูกมัดใดสร้างขอบเขตหรือไม่? เกิดอะไรขึ้นexitถ้าไม่ใช่สคริปต์?

7
ฉันจะทำให้สคริปต์ทุบตีแข็งขึ้นเพื่อป้องกันอันตรายเมื่อมีการเปลี่ยนแปลงในอนาคตได้อย่างไร
ดังนั้นฉันจึงลบโฟลเดอร์บ้านของฉัน (หรืออย่างแม่นยำยิ่งขึ้นไฟล์ทั้งหมดที่ฉันมีสิทธิ์เข้าถึงเพื่อเขียน) สิ่งที่เกิดขึ้นคือฉันมี build="build" ... rm -rf "${build}/"* ... <do other things with $build> ในสคริปต์ทุบตีและหลังจากต้องไม่$buildเอาการประกาศและการใช้งานได้ทั้งหมด - rmแต่ rm -rf /*ทุบตีอย่างมีความสุขที่จะขยาย ใช่. ฉันรู้สึกงี่เง่าติดตั้งข้อมูลสำรองทำให้งานที่ฉันทำหายไป พยายามที่จะย้ายผ่านความอับอาย ตอนนี้ฉันสงสัยว่าอะไรคือเทคนิคในการเขียนสคริปต์ทุบตีเพื่อให้ข้อผิดพลาดดังกล่าวไม่สามารถเกิดขึ้นได้หรืออย่างน้อยก็มีโอกาสน้อย? ตัวอย่างเช่นถ้าฉันเขียน FileUtils.rm_rf("#{build}/*") ในสคริปต์ Ruby ผู้แปลก็จะบ่นbuildว่าไม่ได้ถูกประกาศดังนั้นภาษาก็ช่วยปกป้องฉัน สิ่งที่ฉันได้พิจารณาในการทุบตีนอกเหนือจากการจับกลุ่มrm(ซึ่งเป็นคำตอบมากมายในคำถามที่เกี่ยวข้องพูดถึงไม่ได้เป็น unproblematic): rm -rf "./${build}/"* นั่นคงจะฆ่างานปัจจุบันของฉัน (repo Git) แต่ไม่มีอะไรอื่น ตัวแปร / การกำหนดพารามิเตอร์ของrmนั้นต้องมีการโต้ตอบเมื่อทำหน้าที่ภายนอกไดเรกทอรีปัจจุบัน (ไม่พบสิ่งใด) ลักษณะพิเศษที่คล้ายกัน มันเป็นหรือมีวิธีอื่นในการเขียนสคริปต์ทุบตีที่ "แข็งแกร่ง" ในแง่นี้หรือไม่?
46 bash  shell-script  rm 

3
ค้นหา tmp dir ที่ถูกต้องบนหลาย ๆ แพลตฟอร์ม
ฉันมีสคริปต์ที่ต้องการสร้างไฟล์ชั่วคราวสำหรับการทำงานและล้างข้อมูลหลังจากนั้น คำถามของฉันเกี่ยวกับการค้นหาไดเรกทอรีฐานที่เหมาะสมสำหรับไฟล์ชั่วคราว สคริปต์ต้องทำงานกับหลายแพลตฟอร์ม: Git Bash (Windows), Solaris, Linux, OSX ในแต่ละแพลตฟอร์มไดเรกทอรีชั่วคราวที่ต้องการจะแสดงแตกต่างกัน: Windows: %TMP%(และอาจเป็นไปได้%TEMP%) OSX: $TMPDIR Linux, UNIX: น่าจะเป็น$TMPDIRแต่ดูเหมือนว่าจะไม่มีการตั้งค่าในหลาย ๆ ระบบที่ฉันได้ลอง ดังนั้นในสคริปต์ของฉันฉันเพิ่มแผ่นสำเร็จรูปนี้: if test -d "$TMPDIR"; then : elif test -d "$TMP"; then TMPDIR=$TMP elif test -d /var/tmp; then TMPDIR=/var/tmp else TMPDIR=/tmp fi ดูเหมือนว่าน่าเบื่อเกินไป มีวิธีที่ดีกว่า?

13
วิธีบรรทัดคำสั่งอย่างรวดเร็วเพื่อสลับระหว่างหลายไดเรกทอรีสำหรับการบริหารระบบคืออะไร?
วิธีบรรทัดคำสั่งอย่างรวดเร็วเพื่อสลับระหว่างหลายไดเรกทอรีสำหรับการบริหารระบบคืออะไร? ฉันหมายถึงฉันสามารถใช้pushd .และpopdสลับได้ แต่ถ้าฉันต้องการเก็บทวีคูณและวนรอบพวกมันแทนที่จะโผล่มันออกอย่างถาวรที่ด้านล่างของสแต็ก

8
เหตุใดยูทิลิตี้บังคับ POSIX จึงไม่ได้สร้างไว้ในเชลล์?
จุดประสงค์ของคำถามนี้คือเพื่อตอบสนองความอยากรู้อยากเห็นไม่ใช่เพื่อแก้ปัญหาการคำนวณโดยเฉพาะ คำถามคือ: เหตุใดยูทิลิตี้บังคับ POSIX จึงไม่ได้สร้างอยู่ในการใช้งานเชลล์? ตัวอย่างเช่นฉันมีสคริปต์ที่อ่านไฟล์ข้อความเล็ก ๆ น้อย ๆ และตรวจสอบว่ามีการฟอร์แมตอย่างถูกต้อง แต่ใช้เวลา 27 วินาทีในการเรียกใช้บนเครื่องของฉันเนื่องจากมีการจัดการสตริงจำนวนมาก การจัดการสตริงนี้สร้างกระบวนการใหม่นับพันโดยเรียกโปรแกรมอรรถประโยชน์ต่าง ๆ ดังนั้นความเชื่องช้า ผมค่อนข้างมั่นใจว่าถ้าบางส่วนของสาธารณูปโภคที่ถูกสร้างขึ้นในคือgrep, sed, cut, trและexprแล้วสคริปต์ที่จะวิ่งในครั้งที่สองหรือน้อยกว่า (ขึ้นอยู่กับประสบการณ์ของผมใน C) ดูเหมือนว่าจะมีหลายสถานการณ์ที่การสร้างโปรแกรมอรรถประโยชน์เหล่านี้จะสร้างความแตกต่างระหว่างว่าโซลูชันในเชลล์สคริปต์มีประสิทธิภาพที่ยอมรับได้หรือไม่ เห็นได้ชัดว่ามีเหตุผลที่เลือกที่จะไม่สร้างยูทิลิตี้เหล่านี้ในตัวอาจมียูทิลิตี้หนึ่งเวอร์ชันในระดับระบบเพื่อหลีกเลี่ยงการมียูทิลิตี้รุ่นนั้นไม่เท่ากันหลายรุ่น ฉันไม่สามารถคิดด้วยเหตุผลอื่น ๆ อีกมากมายที่จะรักษาค่าใช้จ่ายในการสร้างกระบวนการใหม่จำนวนมากและ POSIX กำหนดเพียงพอเกี่ยวกับยูทิลิตี้ที่ดูเหมือนว่าปัญหาจะมีการใช้งานที่แตกต่างกันไม่มาก ไม่ขัดขืน อย่างน้อยก็ไม่เป็นปัญหาใหญ่เท่าความไร้ประสิทธิภาพของการมีกระบวนการมากมาย

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