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

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

3
เครื่องหมายวงเล็บในเงื่อนไข if: เหตุใดฉันจึงได้รับข้อผิดพลาดทางไวยากรณ์โดยไม่มีช่องว่าง
ฉันใช้สคริปต์ด้านล่างเพื่อย้ายสองวันกลับเมื่อสคริปต์ทำงานที่เริ่มต้นสองวันของปีและตรวจสอบวันแรกและวันที่สองของทุกเดือนและย้ายกลับสองวัน if [$month="01"] && [$day="01"]; then date="$last_month/$yes_day/$last_year" fulldate="$last_month/$yes_day/$last_year" else if [$month="01"] && [$day="02"]; then date="$last_month/$yes_day/$last_year" fulldate="$last_month/$yes_day/$last_year" else if [ $day = "01" ]; then date="$last_month/$yes_day/$year" fulldate="$year$last_month$yes_day" else if [ $day = "02" ]; then date="$last_month/$yes_day/$year" fulldate="$year$last_month$yes_day" else date="$month/$yes_day/$year" fulldate="$year$month$yes_day" fi fi fi fi แต่ฉันไม่ดีได้รับข้อความแสดงข้อผิดพลาดด้านล่าง Etime_script.sh: line 19: [06=01]: command not …

1
การดีบักสคริปต์ความแตกต่างระหว่าง -x ถึง set -euxo pipefail คืออะไร
วิธีหลักที่ฉันรู้ว่าการดีบักสคริปต์คือการเพิ่ม-xไปที่ shabang ( #!/bin/bash -x) เมื่อเร็ว ๆ นี้ฉันได้พบกับวิธีการใหม่เพิ่มset -euxo pipefailสิทธิใต้ shabang เช่นเดียวกับใน: #!/bin/bash set -euxo pipefail อะไรคือข้อแตกต่างที่สำคัญระหว่างสองวิธีในการดีบัก มีบางครั้งที่คุณอยากได้คนที่เหนือกว่าคนอื่นหรือไม่? ในฐานะน้องใหม่หลังจากอ่านที่นี่ฉันไม่สามารถแยกข้อสรุปเช่นนั้นได้

4
คำนำหน้าและสตริงต่อท้ายไปยังแต่ละบรรทัดออกจากคำสั่ง
ฉันพบปัญหาขณะพยายามเขียนสคริปต์ Bash เมื่อgrepผลลัพธ์มันจะส่งคืน (ปกติ) หลายบรรทัด ฉันต้องการคำนำหน้าและต่อท้ายสตริงกับแต่ละบรรทัดเอาต์พุตเหล่านี้ ฉันยังต้องการที่จะทราบว่าฉันท่อlsเข้าgrepเช่น: ls | grep

3
วิธีการตัดเครื่องหมายทับสุดท้ายของเส้นทางไดเรกทอรี?
ฉันมีสคริปต์ที่ต้องการไดเรกทอรีเป็นหนึ่งอาร์กิวเมนต์ ฉันต้องการที่จะสนับสนุนทั้งสองรูปแบบ: หนึ่งเหมือน a/b/c (ไม่มีฟันแทงตอนท้าย) และอีกอันก็เหมือน a/b/c/ (มีเครื่องหมายทับที่ท้าย) คำถามของฉัน: ด้วยรูปแบบใดรูปแบบหนึ่งทั้งสองฉันจะเปลี่ยนรูปแบบแรกให้เป็นแบบเดิมได้อย่างไรและตัดเครื่องหมายสแลชสุดท้ายของรูปแบบที่สองเพื่อแปลงเป็นรูปแบบแรก

3
การหาสคริปต์ Bash - ส่งคืนข้อผิดพลาดแทนที่จะออกหรือไม่
ฉันกำลังหาสคริปต์ทุบตีในเทอร์มินัลดังนั้นออกจากข้อผิดพลาดด้วย set -o errexit ฆ่า terminal ของฉันซึ่งเป็นสิ่งที่น่ารำคาญอย่างมากเพราะฉันต้องปิดเครื่องเทอร์มินัลเปิดอีกอันหนึ่งและรีเซ็ตตัวแปรบางตัว จนถึงตอนนี้การใช้ command || return บรรทัดในสคริปต์ทำสิ่งที่ฉันต้องการอย่างแน่นอน set -o errexit ที่จะทำ ... แต่ฉันต้องการให้มันทำเพื่อทั้งสคริปต์; ไม่ใช่แค่หนึ่งบรรทัด / คำสั่ง ฉันมีไฟล์ที่เต็มไปด้วยคำสั่งสำหรับการตั้งค่าไซต์และฉันไม่ควรทำคำสั่ง || กลับ สำหรับทุก ๆ บรรทัดในไฟล์ มีตัวเลือกชุดอื่นหรืออะไรที่จะ "คืน" แทนที่จะออกจากเทอร์มินัล - เพื่อความชัดเจนฉันต้องการฆ่าสคริปต์และออกจากเทอร์มินัลในสถานะเดียวกับที่กด ctrl + C เพื่อฆ่าเซอร์วิสที่รันในเทอร์มินัล command || returnทำอย่างนั้น แต่ฉันไม่ต้องการที่จะยึดติด|| returnกับทุกบรรทัดในไฟล์ ดังนั้นฉันกำลังมองหาสิ่งที่คล้ายกับset -o errexitที่ไม่ได้ทำให้สถานีปิดตัวลง --- หมายเหตุ: การสร้างสคริปต์โง่ที่มีสองบรรทัดในนั้น (super.sh): create_path=~/Desktop/site_builder/create.sh source …

5
ฉันจะลบทุกอย่างได้จนกว่าจะมีรูปแบบและทุกอย่างหลังจากรูปแบบอื่นจากบรรทัดได้อย่างไร
ในไฟล์ต่อไปนี้: Lorem ipsum dolor amet amet, consectetuer adipiscing elit เป็นตัวบ่งชี้ที่ดีที่สุดของคุณ Maecenas rhoncus ฉันต้องการลบทุกอย่างก่อนconsectetuerและทุกอย่างหลังจากelitนั้น ผลลัพธ์ที่ฉันต้องการ: consectetuer adipiscing elit. ฉันจะทำสิ่งนี้ได้อย่างไร

4
ฉันจะแสดงชื่อผู้ใช้และ / หรือโฮมไดเร็กตอรี่ทั้งหมดได้อย่างไร?
ฉันต้องการแสดงรายการผู้ใช้ทั้งหมดบนเครื่องโดยปกติแล้วฉันจะทำ: ls -l /home แต่ฉันใช้มันในสคริปต์ที่จะติดตั้งบนเครื่องอื่นและอาจใช้กับเครื่องที่พวกเขาไม่เรียกมันว่าบ้าน (เช่น myHome) ls -l ~ดังนั้นผมจึงต้องการที่จะพูดคุยมัน แต่มันจะแสดงรายชื่อผู้ใช้ที่บ้านของฉันแทนที่จะเป็นชื่อผู้ใช้ที่บ้าน (โดยทั่วไปฉันต้องการรับรายชื่อผู้ใช้บนเครื่อง) ฉันจะพูดคุยเรื่องนี้ได้อย่างไร

6
เลือกล่ามหลังจากเริ่มต้นสคริปต์เช่นถ้า / else อยู่ใน hashbang
มีวิธีใดบ้างในการเลือกล่ามที่กำลังเรียกใช้สคริปต์แบบไดนามิก ฉันมีสคริปต์ที่ฉันใช้ในระบบที่แตกต่างกันสองระบบและล่ามที่ฉันต้องการใช้นั้นจะอยู่ในตำแหน่งที่ตั้งที่ต่างกันในทั้งสองระบบ สิ่งที่ฉันต้องทำคือเปลี่ยนสาย hashbang ทุกครั้งที่เปลี่ยนไป ฉันต้องการทำบางสิ่งที่เทียบเท่ากับตรรกะของสิ่งนี้ (ฉันรู้ว่าการสร้างที่แน่นอนนี้เป็นไปไม่ได้): if running on system A: #!/path/to/python/on/systemA elif running on system B: #!/path/on/systemB #Rest of script goes here หรือจะดีกว่านี้ก็เพื่อให้พยายามใช้ล่ามตัวแรกและหากไม่พบมันจะใช้ตัวที่สอง: try: #!/path/to/python/on/systemA except: #!path/on/systemB #Rest of script goes here เห็นได้ชัดว่าผมแทนสามารถดำเนินการได้เป็น /path/to/python/on/systemA myscript.py หรือ /path/on/systemB myscript.py ขึ้นอยู่กับที่ผม แต่ที่จริงผมมีสคริปต์เสื้อคลุมที่เปิดตัวmyscript.pyดังนั้นผมอยากจะระบุเส้นทางไปล่ามหลามทางโปรแกรมมากกว่าด้วยมือ

1
ลบความเงียบออกจากไฟล์เสียงขณะที่ยังคงช่องว่าง
ขณะนี้เรากำลังใช้คำสั่งนี้ภายในเชลล์สคริปต์เพื่อลบความเงียบออกจากไฟล์เสียง: ffmpeg -i $INFILE -af silenceremove=0:0:0:-1:1:${NOISE_TOLERANCE}dB -ac 1 $SILENCED_FILE -y ใช้งานได้ดียกเว้นว่าจะลบความเงียบทั้งหมดทำให้เสียงที่เหลืออยู่ถูกบีบเข้าด้วยกัน วิธีนี้สามารถทำได้ในขณะที่เหลือสองหรือสามวินาทีระหว่างเสียงแต่ละส่วน? โซลูชันต้องมีประสิทธิภาพมากเนื่องจากเราจะประมวลผลเสียงจำนวนมากและควรใช้เครื่องมือที่สามารถติดตั้งได้อย่างง่ายดายบนทั้ง Linux และ OSX เช่น ffmpeg หรือ sox

5
บีบอัดไฟล์ขนาดใหญ่จำนวนมากอย่างรวดเร็ว
ฉันมีการสร้างข้อมูลบันทึกข้อมูลประมาณ 200 GB ต่อวันกระจายอยู่ในไฟล์บันทึกต่างๆประมาณ 150 ไฟล์ ฉันมีสคริปต์ที่ย้ายไฟล์ไปยังตำแหน่งชั่วคราวและทำ tar-bz2 ในไดเรกทอรีชั่วคราว ฉันได้รับผลลัพธ์ที่ดีเนื่องจากมีการบีบอัดบันทึก 200 GB ถึงประมาณ 12-15 GB ปัญหาคือมันใช้เวลาตลอดไปในการบีบอัดไฟล์ cronงานทำงานที่ 02:30 ทุกวันและยังทำงานต่อไปจนถึง 5: 00-6: 12:00 มีวิธีปรับปรุงความเร็วของการบีบอัดและทำให้งานเสร็จเร็วขึ้นหรือไม่ ความคิดใด ๆ ไม่ต้องกังวลกับกระบวนการอื่น ๆ ทั้งหมดตำแหน่งที่มีการบีบอัดเกิดขึ้นบนNASและฉันสามารถเรียกใช้ NAS บนVMเฉพาะและเรียกใช้สคริปต์การบีบอัดจากที่นั่น นี่คือการส่งออกของด้านบนสำหรับการอ้างอิง: top - 15:53:50 up 1093 days, 6:36, 1 user, load average: 1.00, 1.05, 1.07 Tasks: 101 total, 3 running, …

1
เหตุใด bash fork bombs จึงทำงานต่างกันและความสำคัญของมันคืออะไร?
ฉันรู้ว่า Fork fork แบบธรรมดาทำงานได้อย่างไร แต่ฉันไม่เข้าใจว่าทำไม & ในตอนท้ายของการวางระเบิด bash fork ทั่วไปและทำไมสคริปต์เหล่านี้จึงมีความแตกต่าง: :(){ (:) | (:) }; : และ :(){ : | :& }; : อดีตทำให้การใช้งาน cpu ขัดขวางก่อนที่จะทิ้งฉันกลับไปที่หน้าจอเข้าสู่ระบบ หลังทำให้ระบบของฉันค้างแข็งแทนที่จะบังคับให้ฉันรีบูตยาก ทำไมถึงเป็นอย่างนั้น? ทั้งสองอย่างต่อเนื่องสร้างกระบวนการใหม่ดังนั้นทำไมระบบทำงานแตกต่างกันอย่างไร สคริปต์ทั้งสองยังทำงานแตกต่างจาก :(){ : | : }; : ซึ่งไม่ได้ทำให้เกิดปัญหาใด ๆ เลยถึงแม้ว่าฉันจะคาดหวังให้พวกเขาเหมือนกัน หน้าคู่มือทุบตีระบุว่าคำสั่งในไปป์ไลน์ถูกดำเนินการแล้วใน subshell ดังนั้นฉันจึงเชื่อว่า: | : ควรเพียงพอแล้ว ฉันเชื่อ & ควรเรียกใช้ไปป์ไลน์ใน subshell ใหม่ …

5
นี่เป็นข้อบกพร่องในการทุบตีหรือไม่? `return 'ไม่ออกจากฟังก์ชั่นถ้าเรียกจากไพพ์
ฉันมีปัญหาแปลก ๆ กับทุบตีเมื่อเร็ว ๆ นี้ ในขณะที่พยายามทำให้สคริปต์ของฉันง่ายขึ้นฉันได้รับโค้ดเล็ก ๆ นี้: $ o(){ echo | while read -r; do return 0; done; echo $?;}; o 0 $ o(){ echo | while read -r; do return 1; done; echo $?;}; o 1 returnควรออกจากฟังก์ชั่นโดยไม่พิมพ์$?ใช่มั้ย ถ้าอย่างนั้นฉันจะตรวจสอบว่าฉันสามารถกลับจากท่อเพียงอย่างเดียว: $ echo | while read -r; do return 1; done …

4
เปรียบเทียบสองคอลัมน์ของไฟล์ต่างกันและพิมพ์ถ้ามันตรงกัน
ฉันใช้ Solaris 10 และตัวเลือก grep ที่เกี่ยวข้องกับ -f ไม่ทำงาน ฉันมีไฟล์สองไฟล์ที่คั่นด้วย pipe: file1: abc|123|BNY|apple| cab|234|cyx|orange| def|kumar|pki|bird| ไฟล์ 2: abc|123| kumar|pki| cab|234 ฉันต้องการเปรียบเทียบสองคอลัมน์แรกของ file2 กับ file1 (ค้นหาเนื้อหาทั้งหมดของ file1 ในสองคอลัมน์แรก) หากตรงกับพิมพ์บรรทัดที่ตรงกันของ file1 จากนั้นค้นหาบรรทัดที่สองของไฟล์ 2 และอื่น ๆ ผลลัพธ์ที่คาดหวัง: abc|123|BNY|apple| cab|234|cyx|orange| ไฟล์ที่ฉันมีมีขนาดใหญ่มากมีประมาณ 400,000 บรรทัดดังนั้นฉันต้องการทำให้การดำเนินการเป็นไปอย่างรวดเร็ว

4
มี ssh-add เงียบถ้ามีกุญแจอยู่แล้ว
ฉันต้องการที่จะวางssh-add /path/to/special_keyที่ด้านบนของสคริปต์ วิธีนี้ใช้งานได้ดี แต่จะพร้อมท์ให้ใส่ข้อความรหัสผ่านเสมอ นี่เป็นเรื่องแปลกและน่ารำคาญเล็กน้อยเพราะมันยังถามรหัสผ่านถึงแม้ว่าจะssh-add -lแสดงว่ามีการเพิ่มรหัสแล้ว มีวิธีบอกหรือไม่ว่า: "เพิ่มรหัสนี้และถามวลีรหัสผ่านหากยังไม่ได้เพิ่มหรือไม่ทำอะไรเลย"

5
ฟังก์ชันทุบตี stateful
ฉันต้องการใช้ฟังก์ชั่นใน Bash ซึ่งจะเพิ่มจำนวน (และคืน) จำนวนการโทรทุกครั้ง น่าเสียดายที่นี่ดูไม่สำคัญเพราะฉันเรียกใช้ฟังก์ชั่นภายใน subshell และดังนั้นจึงไม่สามารถแก้ไขตัวแปรของ parent shell ได้ นี่คือความพยายามของฉัน: PS_COUNT=0 ps_count_inc() { let PS_COUNT=PS_COUNT+1 echo $PS_COUNT } ps_count_reset() { let PS_COUNT=0 } นี้จะใช้ดังนี้ (และด้วยเหตุนี้ฉันต้องเรียกใช้ฟังก์ชันจาก subshell): PS1='$(ps_count_reset)> ' PS2='$(ps_count_inc) ' ด้วยวิธีนี้ฉันจะได้รับพรอมต์หลายบรรทัดที่มีหมายเลข: > echo 'this 1 is 2 a 3 test' น่ารัก แต่เนื่องจากข้อ จำกัด ดังกล่าวไม่ทำงาน โซลูชันที่ไม่ทำงานจะเขียนจำนวนลงในไฟล์แทนตัวแปร อย่างไรก็ตามสิ่งนี้จะสร้างความขัดแย้งระหว่างเซสชันหลายเซสชันพร้อมกัน ฉันสามารถต่อท้าย ID …

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