Có thể kết hợp đầu ra từ hai lệnh này?
node ~/projects/trunk/index.js
python ~/projects/trunk/run.py run
Không có lệnh nào thoát ra nên tôi không biết phải làm thế nào.
Có thể kết hợp đầu ra từ hai lệnh này?
node ~/projects/trunk/index.js
python ~/projects/trunk/run.py run
Không có lệnh nào thoát ra nên tôi không biết phải làm thế nào.
Câu trả lời:
Bạn có thể kết hợp hai lệnh bằng cách nhóm nó với { }
:
{ command1 & command2; }
cho đến nay, bạn có thể chuyển hướng nhóm đến một tệp (cuối cùng ;
trước đó }
là bắt buộc):
{ command1 & command2; } > new_file
nếu bạn muốn tách STDOUT
và STDERR
trong hai tệp:
{ command1 & command2; } > STDOUT_file 2> STDERR_file
;
trước }
, điều đó là bắt buộc!
{ yes {1..20} & yes {1..20}; } | grep -v '^1 2 3'
lý tưởng là không in bất cứ điều gì nếu dòng không bị hỏng.
&&
thay vì &
! command1 & command2
- điều này chạy lệnh1 trong nền và bắt đầu lệnh2 ngay lập tức, do đó chạy cả hai lệnh song song và làm rối đầu ra. command1 && command2
- cái này chạy lệnh1 (ở nền trước) và sau đó, nếu lệnh1 bị ép, chạy lệnh2.
Tổng quát hơn, có thể sử dụng nhóm con hoặc nhóm lệnh và chuyển hướng đầu ra của cả nhóm cùng một lúc.
Mã số:
( command1 ; command2 ; command3 ) | cat
{ command1 ; command2 ; command3 ; } > outfile.txt
Sự khác biệt chính giữa hai cái là cái thứ nhất tách ra của một tiến trình con, trong khi cái thứ hai hoạt động trong bối cảnh của shell chính. Điều này có thể có hậu quả liên quan đến việc thiết lập và sử dụng các biến và các cài đặt môi trường khác, cũng như hiệu suất.
Đừng quên rằng khung đóng trong nhóm lệnh (và các hàm) phải được tách biệt khỏi nội dung bằng dấu chấm phẩy hoặc dòng mới. Điều này là do "}"
thực sự là một lệnh (từ khóa) của riêng nó và phải được xử lý như một lệnh.
( )
hoạt động tốt quá.
}
không phải là một lệnh ở tất cả. Đó là một từ dành riêng. Cùng đi cho {
. Tôi thường viết những danh sách như vậy : { command1;command2;} > outfile.txt
. Bạn có thể thêm dấu cách sau dấu chấm phẩy nhưng không cần thiết. Không gian sau {
là cần thiết, mặc dù.
( yes {1..20} & yes {1..20}; ) | grep -v '^1 2 3'
lý tưởng là không in bất cứ điều gì nếu dòng không bị hỏng. (H / t đến @antak).
( command1 && command2 && command3 ) | cat
()
như với dấu ngoặc nhọn, {}
nó chạy như một tiến trình nền và sau đó bạn phải xử lý kết quả đầu ra từ đó. Cũng ống cho mèo `| cat` là một thay thế đẹp hơn sau đó `> / dev / stdout`
Tôi đã kết thúc việc này, các đề xuất khác không hoạt động, vì lệnh thứ 2 hoặc bị giết hoặc không bao giờ được thực thi.
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
mặc dù tôi chưa bao giờ thấy đây là sự cố với 2 quy trình khác nhau ghi vào cùng một tệp nhật ký.
yes {1..20}
lệnh2 = yes {1..20}
và dẫn đầu ra kết hợp qua | grep -v '^1 2 3'
đó lý tưởng là không in bất cứ thứ gì nếu dòng không bị hỏng. (H / t đến @antak).
Thử đi:
paste $(node ~/projects/trunk/index.js) $(python ~/projects/trunk/run.py run) > outputfile
Hầu hết các giải pháp cho đến nay xử lý tồi với vấn đề một phần dòng. Giả sử trong một giây rằng các chương trình là:
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
Khi chạy song song bạn muốn đầu ra có đầy đủ các dòng a
s theo sau là các dòng b
s đầy đủ . Những gì bạn không muốn là a
s và b
s trộn trên cùng một dòng ( tr -s ab
thay thế lặp lại a
s bằng một lần duy nhất a
, vì vậy sẽ dễ dàng hơn để xem điều gì xảy ra):
# This is bad - half lines are mixed
$ (cmd1 & cmd2 ) | tr -s ab
bababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababa
ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
Thay vào đó, nếu bạn sử dụng GNU Parallel, bạn sẽ có được các dòng đầy đủ sạch với a
s hoặc b
s nhưng không bao giờ bị trộn lẫn:
$ parallel --line-buffer ::: cmd1 cmd2 | tr -s ab
a
a
b
b
b
b
a
Các phiên bản mới hơn của GNU Parallel thậm chí còn tránh làm đầy đĩa của bạn: Phần trên có thể chạy mãi mãi.
Đối với trường hợp đặc biệt là kết hợp nhiều đầu ra lệnh BASH vào một dòng, đây là công thức để lần lượt chạy từng lệnh, loại bỏ bất kỳ dòng mới nào giữa các đầu ra của chúng.
(echo 'ab' && echo 'cd' && echo 'ef') | tr -d '\n'
>>> abcdef
Như một ví dụ trong thế giới thực, mã bên dưới sẽ nhúng một thông điệp ASCII giữa hai chuỗi byte cố định (tạo thành một lệnh in, trong trường hợp này)
# 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
(Lưu ý: phương pháp này chỉ hoạt động nếu lệnh thoát. Để kết hợp thiết bị xuất chuẩn từ các lệnh không thoát, hãy xem các câu trả lời khác.)