เป็นไปได้ไหมที่จะรวมเอาท์พุทจากคำสั่งทั้งสองนี้?
node ~/projects/trunk/index.js
python ~/projects/trunk/run.py run
ไม่มีคำสั่งออกดังนั้นฉันไม่แน่ใจว่าจะทำอย่างไร
เป็นไปได้ไหมที่จะรวมเอาท์พุทจากคำสั่งทั้งสองนี้?
node ~/projects/trunk/index.js
python ~/projects/trunk/run.py run
ไม่มีคำสั่งออกดังนั้นฉันไม่แน่ใจว่าจะทำอย่างไร
คำตอบ:
คุณสามารถรวมสองคำสั่งโดยการจัดกลุ่มมันด้วย{ }
:
{ command1 & command2; }
ป่านฉะนี้คุณสามารถเปลี่ยนเส้นทางกลุ่มไปยังไฟล์ (สุดท้าย;
ก่อนที่จะ}
มีผลบังคับใช้):
{ command1 & command2; } > new_file
หากคุณต้องการแยกSTDOUT
และเป็นSTDERR
สองไฟล์:
{ command1 & command2; } > STDOUT_file 2> STDERR_file
;
ก่อนหน้า}
นี้มันบังคับ!
{ yes {1..20} & yes {1..20}; } | grep -v '^1 2 3'
ซึ่งจะไม่พิมพ์อะไรเลยหากเส้นไม่แตก
&&
แทน&
! command1 & command2
- สิ่งนี้จะรัน command1 ในพื้นหลังและเริ่ม command2 ทันทีดังนั้นจึงรันทั้งสองคำสั่งในแบบขนานและ messing up output command1 && command2
- สิ่งนี้จะรัน command1 (เบื้องหน้า) และจากนั้นหาก command1 ยอมให้รัน command2
โดยทั่วไปแล้วเป็นไปได้ที่จะใช้การแบ่งกลุ่มย่อยหรือการจัดกลุ่มคำสั่งและเปลี่ยนเส้นทางการส่งออกของกลุ่มทั้งหมดในครั้งเดียว
รหัส:
( command1 ; command2 ; command3 ) | cat
{ command1 ; command2 ; command3 ; } > outfile.txt
ความแตกต่างที่สำคัญระหว่างสองคือกระบวนการแรกแยกกระบวนการลูกในขณะที่กระบวนการที่สองทำงานในบริบทของเชลล์หลัก สิ่งนี้อาจมีผลตามมาเกี่ยวกับการตั้งค่าและการใช้ตัวแปรและการตั้งค่าสภาพแวดล้อมอื่น ๆ รวมถึงประสิทธิภาพ
อย่าลืมว่าวงเล็บปิดในการจัดกลุ่มคำสั่ง (และฟังก์ชั่น) จะต้องแยกออกจากเนื้อหาด้วยเครื่องหมายอัฒภาคหรือขึ้นบรรทัดใหม่ นี่เป็นเพราะ"}"
จริงๆแล้วคำสั่ง (คำหลัก) ของมันเองและจะต้องได้รับการปฏิบัติเหมือนเป็นหนึ่งเดียว
( )
งานได้ดีเช่นกัน
}
ไม่ใช่คำสั่งเลย มันเป็นคำที่สงวนไว้ {
เดียวกันจะไปสำหรับ { command1;command2;} > outfile.txt
ฉันมักจะเขียนรายชื่อดังกล่าวเช่นดังนั้น: คุณสามารถเพิ่มช่องว่างหลังเซมิโคลอน แต่ไม่จำเป็น แม้ว่าพื้นที่หลังจากนั้น{
เป็นสิ่งจำเป็น
( yes {1..20} & yes {1..20}; ) | grep -v '^1 2 3'
ซึ่งจะไม่พิมพ์อะไรเลยหากเส้นไม่แตก (H / t ถึง @antak)
( command1 && command2 && command3 ) | cat
()
เช่นเดียวกับวงเล็บปีกกา{}
มันทำงานเป็นความคืบหน้าพื้นหลังและจากนั้นคุณต้องจัดการกับผลลัพธ์จากที่ ยังท่อไปยังแมว `| cat` เป็นทางเลือกที่ใหม่กว่า `> / dev / stdout`
ฉันลงเอยด้วยการทำสิ่งนี้ข้อเสนอแนะอื่น ๆ ไม่ทำงานเนื่องจากคำสั่งที่ 2 ถูกฆ่าหรือไม่ดำเนินการ
alias app () {
nohup python ~/projects/trunk/run.py run 1>/tmp/log 2>&1 &
echo $! > /tmp/api.pid
nohup node ~/projects/trunk/index.js 1>/tmp/log 2>&1 &
echo $! > /tmp/client.pid
tail -f /tmp/log
}
tail -f *.log
แม้ว่าฉันไม่เคยเห็นนี่เป็นปัญหากับโพรเซสที่ต่างกัน 2 โพรเซสที่เขียนไปยังล็อกไฟล์เดียวกัน
yes {1..20}
command2 = yes {1..20}
และไพพ์เอาท์พุทที่รวมกัน| grep -v '^1 2 3'
ซึ่งจะไม่พิมพ์สิ่งใดหากบรรทัดไม่ได้ขาด (H / t ถึง @antak)
ลองสิ่งนี้:
paste $(node ~/projects/trunk/index.js) $(python ~/projects/trunk/run.py run) > outputfile
การแก้ปัญหาส่วนใหญ่จนถึงปัญหาเส้นบางส่วนไม่ดี สมมติว่าโปรแกรมเป็นวินาที:
cmd1() {
perl -e 'while(1) { print "a"x3000_000,"\n"}'
}
export -f cmd1
cmd2() {
perl -e 'while(1) { print "b"x3000_000,"\n"}'
}
export -f cmd2
เมื่อเรียกใช้งานแบบขนานคุณต้องการให้เอาต์พุตมีเส้นเต็มของa
s ตามด้วยเส้นเต็มของb
s สิ่งที่คุณไม่ต้องการa
และb
s ผสมในบรรทัดเดียวกัน ( tr -s ab
แทนการทำซ้ำa
s มีเพียงหนึ่งเดียวa
ดังนั้นจึงเป็นเรื่องง่ายที่จะเห็นสิ่งที่เกิดขึ้น):
# This is bad - half lines are mixed
$ (cmd1 & cmd2 ) | tr -s ab
bababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababa
ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
ถ้าคุณใช้ GNU Parallel แทนคุณจะได้เส้นที่สะอาดและสมบูรณ์ด้วยa
s หรือb
s แต่ไม่ผสมกัน:
$ parallel --line-buffer ::: cmd1 cmd2 | tr -s ab
a
a
b
b
b
b
a
เวอร์ชั่นใหม่ของ GNU Parallel แม้จะหลีกเลี่ยงการเติมดิสก์ของคุณ: ข้างต้นสามารถทำงานได้ตลอดไป
เนื่องจากคุณใช้อยู่แล้วnode
คุณอาจต้องการลองพร้อมกัน
เรียกใช้หลายคำสั่งพร้อมกัน ชอบ
npm run watch-js & npm run watch-less
แต่ดีกว่า
สำหรับกรณีพิเศษของการรวมคำสั่ง BASH จำนวนมากออกเป็นหนึ่งบรรทัดต่อไปนี้เป็นสูตรการเรียกใช้แต่ละคำสั่งโดยลบบรรทัดใหม่ใด ๆ ระหว่างเอาต์พุต
(echo 'ab' && echo 'cd' && echo 'ef') | tr -d '\n'
>>> abcdef
เป็นตัวอย่างในโลกแห่งความจริงรหัสด้านล่างจะฝังข้อความ ASCII ระหว่างสองสตริงคงที่ของไบต์ (สร้างคำสั่งการพิมพ์ในกรณีนี้)
# hex prefix encode a message as hex hex suffix | strip newline | hex to binary | (then, for example, send the binary over a TCP connection)
(echo '1b40' && echo "Test print #1" | xxd -p && echo '1d564103') | tr -d '\n' | xxd -r -p | nc -N 192.168.192.168 9100
(หมายเหตุ: วิธีนี้ใช้ได้เฉพาะเมื่อคำสั่งออกจากการรวม stdout จากคำสั่งที่ไม่ออกให้ดูคำตอบอื่น ๆ )