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

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

5
วิธีเปรียบเทียบเวอร์ชันของโปรแกรมในเชลล์สคริปต์
สมมติว่าฉันต้องการเปรียบเทียบgccรุ่นเพื่อดูว่าระบบได้ติดตั้งรุ่นขั้นต่ำหรือไม่ ในการตรวจสอบgccเวอร์ชั่นฉันดำเนินการดังต่อไปนี้ gcc --version | head -n1 | cut -d" " -f4 ผลลัพธ์ก็คือ 4.8.5 ดังนั้นฉันจึงเขียนifคำสั่งง่ายๆเพื่อตรวจสอบรุ่นนี้เทียบกับค่าอื่น ๆ if [ "$(gcc --version | head -n1 | cut -d" " -f4)" -lt 5.0.0 ]; then echo "Less than 5.0.0" else echo "Greater than 5.0.0" fi แต่มันเกิดข้อผิดพลาด: [: integer expression expected: 4.8.5 ฉันเข้าใจความผิดพลาดของฉันว่าฉันกำลังใช้สตริงเพื่อเปรียบเทียบและ-ltต้องการจำนวนเต็ม ดังนั้นมีวิธีอื่นในการเปรียบเทียบรุ่นหรือไม่

1
ไฟล์ปฏิบัติการที่ชื่อ 'ทดสอบ' อยู่ใน $ PATH แต่จะไม่ทำงาน
ฉันมีไฟล์ใน $ HOME / bin (ก่อนที่คุณจะถามใช่มันอยู่ในเส้นทางของฉัน) เรียกว่าtestฉันยืนยันว่าสามารถดำเนินการได้ดีเมื่อฉันรันด้วยพา ธ เต็มไปยังไฟล์ อย่างไรก็ตามฉันได้รับปัญหาแปลก ๆ จริง ๆ เมื่อฉันไม่เรียกใช้วิธีนี้ เมื่อฉันเพิ่งรันtestในเทอร์มินัลมันไม่ทำอะไรเลยและส่งคืนทันที ฉันรู้ว่านี่ไม่ใช่ปัญหาในการค้นหาไฟล์ด้วยเหตุผลหลายประการ: ไม่มีข้อความแสดงข้อผิดพลาด โดยปกติหากไม่พบไฟล์หรือไม่สามารถดำเนินการข้อความจะถูกพิมพ์ออกมาโดยบอกว่า การรันwhich testยังคงส่งคืนพา ธ ไฟล์ที่ถูกต้อง น่าจะเป็นที่แปลกประหลาดของทั้งหมด - straceสคริปต์ที่ทำงานได้ดีเมื่อวิ่งผ่าน ฉันพยายามใช้straceเพื่อดูว่าฉันสามารถทราบได้ว่าเกิดอะไรขึ้น แต่เมื่อฉันใช้งานด้วยstraceมันทำงานได้อย่างที่คาดไว้กับปัญหา 0 ข้อ


4
เป็นไปได้ไหมที่จะพิมพ์เนื้อหาของเนื้อหาของตัวแปรด้วย shell script? (การอ้างอิงทางอ้อม)
สมมุติว่าฉันประกาศตัวแปรต่อไปนี้แล้ว: $ var='$test' $ test="my string" หากฉันพิมพ์เนื้อหาของพวกเขาฉันเห็นดังต่อไปนี้: $ echo $var $test $ echo $test my string ฉันต้องการหาวิธีพิมพ์เนื้อหาของเนื้อหาของ$var(ซึ่งเป็นเนื้อหาของ$test) ดังนั้นฉันจึงพยายามทำสิ่งต่อไปนี้: $ echo $(echo $var) $test แต่นี่คือผลลัพธ์$testและไม่ใช่"my string"... เป็นไปได้หรือไม่ที่จะพิมพ์เนื้อหาของตัวแปรโดยใช้ bash?

3
ทำไมต้องตรวจสอบว่าไฟล์นั้นมีอยู่จริงก่อนที่จะทำการจัดหา?
เมื่อพยายามแหล่งที่มาของไฟล์คุณจะไม่ต้องการให้เกิดข้อผิดพลาดในการบอกว่าไฟล์ไม่มีอยู่เพื่อให้คุณรู้ว่าจะแก้ไขอย่างไร ตัวอย่างเช่นnvmแนะนำให้เพิ่มสิ่งนี้ลงในโปรไฟล์ / rc ของคุณ: export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm หากnvm.shไม่มีตัวเลือกข้างต้นคุณจะได้รับ "ข้อผิดพลาดเงียบ" แต่ถ้าคุณลองเอาท์พุทจะเป็น. "$NVM_DIR/nvm.sh"FILE_PATH: No such file or directory

3
ทำไม "ps axe" ไม่พบสคริปต์ทุบตีที่รันอยู่โดยไม่มี“ #!” หัวข้อ?
เมื่อฉันเรียกใช้สคริปต์นี้ตั้งใจให้ทำงานจนกว่าจะฆ่า ... # foo.sh while true; do sleep 1; done ... ฉันไม่สามารถหาได้โดยใช้ps ax: >./foo.sh // In a separate shell: >ps ax | grep foo.sh 21110 pts/3 S+ 0:00 grep --color=auto foo.sh ... แต่ถ้าฉันเพิ่งเพิ่ม#!ส่วนหัว " " ทั่วไปลงในสคริปต์ ... #! /usr/bin/bash # foo.sh while true; do sleep 1; done ... จากนั้นสคริปต์จะสามารถค้นหาได้โดยpsคำสั่งเดียวกัน... >./foo.sh …

2
รันคำสั่ง bash หลังจากคำสั่งพร้อมกันไหม?
ฉันต้องการเรียกใช้คำสั่งแบบขนาน เมื่อคำสั่งทั้งหมดเหล่านี้เสร็จสิ้นให้เริ่มต้นคำสั่งถัดไป ฉันว่าแนวทางต่อไปนี้จะได้ผล #!/bin/bash command1 & command2 & command3 && command4 แต่มันก็ไม่ได้ ฉันจำเป็นต้องเรียกใช้command4เมื่อคำสั่งสามคำแรกเสร็จสิ้นสมบูรณ์


6
การตรวจสอบความถูกต้องของไบนารีคำสั่งก่อนดำเนินการ
มีวิธีการตรวจสอบสิ่งที่คุณกำลังดำเนินการจากสคริปต์ทุบตีจริง ๆ ? บอกว่าทุบตีสคริปต์ของคุณจะถูกเรียกหลายคำสั่ง (ตัวอย่างเช่น: tar, mail, scp, mysqldump) และคุณยินดีที่จะให้แน่ใจว่าtarเป็นจริงจริงtarซึ่งเป็นที่ระบุโดยrootผู้ใช้เป็นไฟล์และไดเรกทอรีแม่เจ้าของและเป็นคนเดียวที่มีสิทธิ์ในการเขียน และไม่ได้/tmp/surprise/tarมีwww-dataหรือapache2เป็นเจ้าของ แน่ใจว่าฉันรู้เกี่ยวกับPATHสภาพแวดล้อมและฉันอยากรู้ว่านี้สามารถตรวจสอบเพิ่มเติมจากสคริปต์ทุบตีทำงานและถ้าเป็นเช่นนั้นได้อย่างไร ตัวอย่าง: (หลอกรหัส) tarfile=$(which tar) isroot=$(ls -l "$tarfile") | grep "root root" #and so on...

2
เหตุใดราคาจึงจำเป็นสำหรับอาร์กิวเมนต์ไฟล์เมื่อเรียกสคริปต์ Bash นี้
ฉันค่อนข้างใหม่กับการเขียนสคริปต์ Bash ฉันมี "testcript" ซึ่งฉันใช้เป็นพื้นฐานสำหรับสคริปต์ขั้นสูง / มีประโยชน์มากขึ้น: #!/bin/bash files=$1 for a in $files do echo "$a" done เมื่อฉันเรียกสิ่งนี้โดยไม่ใส่เครื่องหมายอัญประกาศมันก็แค่หยิบไฟล์หนึ่งไฟล์ในไดเรกทอรี: testscript *.txt แต่เมื่อฉันเรียกมันด้วยเครื่องหมายคำพูดมันทำงานได้อย่างถูกต้องและเลือกไฟล์ข้อความทั้งหมด: testscript '*.txt' เกิดขึ้นที่นี่คืออะไร?

2
มีวิธีใดบ้างที่เชลล์สคริปต์จะรู้ว่าโปรแกรมใดทำงานหรือไม่
ใน * nix world มีวิธีใดที่เชลล์สคริปต์จะมีข้อมูลเกี่ยวกับโปรแกรมที่เรียกใช้งานหรือไม่ ตัวอย่าง: /path/to/script1 /path/to/script_xyz ในสถานการณ์สมมตินี้script_xyzจะมีข้อมูลเส้นทาง ( /path/to/script1) หรือ ประมวลผล PID ของนิติบุคคลที่ได้ดำเนินการ หมายเหตุ: ฉันอยากรู้เกี่ยวกับการแก้ปัญหาและแนวทางที่แตกต่างกันฉันไม่คาดหวังว่าสิ่งนี้จะเป็นไปได้จริง

3
วิธีลบ \ n ระหว่างเอาต์พุตของคำสั่ง echo สองคำสั่ง?
ฉันมีไฟล์ข้อความที่มีชื่อไฟล์หนึ่งชื่อในแต่ละบรรทัด: 111_c4l5r120.png 123_c4l4r60.png 135_c4l4r180.png 147_c4l3r60.png 15_c4l1r120.png ... ฉันต้องการแปลงเป็นรูปนี้: 111_c4l5r120.png 111 123_c4l4r60.png 123 135_c4l4r180.png 135 147_c4l3r60.png 147 15_c4l1r120.png 15 ... ใช้รหัสนี้: #!/bin/bash while IFS='' read -r line || [[ -n "$line" ]]; do echo "$line" >> output.txt echo "$line" | cut -d'_' -f 1 >> output.txt done < "$1" แต่ผลลัพธ์คือ: 111_c4l5r120.png …

2
วิธีลบพารามิเตอร์ตำแหน่งจาก $ @
โดยทั่วไปฉันต้องการ "ถอนออก" เกิดขึ้นครั้งแรก-infจากรายการพารามิเตอร์ (พารามิเตอร์ที่เหลือจะถูกส่งผ่านไปยังคำสั่งอื่น) สคริปต์ที่ฉันมีมีโครงสร้างต่อไปนี้: #!/bin/sh <CODE> for POSITIONAL_PARAM in "$@" do <CODE> if [ "$POSITIONAL_PARAM" = '-inf' ] then <PLUCK $POSITIONAL_PARAM FROM $@> break fi <CODE> done <CODE> some-other-command "$@" # end of script มีวิธีที่ดีในการทำเช่นนี้? BTW แม้ว่าฉันสนใจส่วนใหญ่อยู่ในคำตอบที่ใช้บังคับกับฉันสนใจยังอยู่ในคำตอบเฉพาะ/bin/sh/bin/bash

2
ทำไม“ bash -x” ถึงทำลายสคริปต์นี้?
ฉันมีสคริปต์ที่วัดระยะเวลาที่คำสั่งดำเนินการ มันต้องการtimeคำสั่ง"ของจริง" ความหมายไบนารีเป็นตัวอย่างใน/usr/bin/time(เนื่องจาก bash-built-in ไม่มี-fแฟล็ก) ด้านล่างสคริปต์แบบง่ายซึ่งสามารถดีบั๊กได้: #!/bin/bash TIMESEC=$(echo blah | ( /usr/bin/time -f %e grep blah >/dev/null ) 2>&1 | awk -F. '{print $1}') echo ABC--$TIMESEC--DEF if [ "$TIMESEC" -eq 0 ] ; then echo "we are here!" fi บันทึกเป็น "test.sh" และดำเนินการ: $ bash test.sh ABC--0--DEF we are here! ดังนั้นมันจึงทำงานได้ …

5
ฉันจะทำให้สคริปต์นี้มีข้อผิดพลาดในการออกจากผลของลูปได้อย่างไร
ฉันมีสคริปต์ทุบตีซึ่งใช้set -o errexitเพื่อให้เกิดข้อผิดพลาดสคริปต์ทั้งหมดออกจากที่จุดของความล้มเหลว สคริปต์รันcurlคำสั่งซึ่งบางครั้งล้มเหลวในการดึงไฟล์ที่ต้องการ - อย่างไรก็ตามเมื่อเกิดเหตุการณ์นี้สคริปต์จะไม่เกิดข้อผิดพลาดในการออก ฉันได้เพิ่มการforวนซ้ำไป หยุดชั่วครู่หนึ่งแล้วลองcurlคำสั่งอีกครั้ง ใช้falseที่ด้านล่างของ for for loop เพื่อกำหนดสถานะการออกไม่เป็นศูนย์เริ่มต้น - หากคำสั่ง curl สำเร็จ - การแบ่งลูปและสถานะการออกของคำสั่งสุดท้ายควรเป็นศูนย์ #! /bin/bash set -o errexit # ... for (( i=1; i<5; i++ )) do echo "attempt number: "$i curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim if [ -f ~/.vim/autoload/pathogen.vim ] then echo "file has …

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