Làm cách nào tôi có thể tách một quá trình từ tập lệnh bash?


18

Tôi đang cố gắng tách một quy trình khỏi tập lệnh bash để SIGINT sẽ không được chuyển tiếp đến quy trình khi tôi thoát tập lệnh.

Tôi đã sử dụng disownlệnh trong thiết bị đầu cuối trực tiếp, tuy nhiên trong bash, disownkhông ngăn SIGINT được chuyển tiếp. Mục đích của tập lệnh này là bắt đầu openocd và sau đó gdb với một lệnh gọi duy nhất. Vì tập lệnh không bao giờ thoát (nó đang chạy gdb) nên SIGINT vẫn được chuyển tiếp từ gdb sang openocd, đây là một vấn đề vì SIGINT được sử dụng làm lệnh tạm dừng trong gdb.

Trong thiết bị đầu cuối, nó sẽ trông giống như thế này:

$ openocd &    # run openocd demonized
$ disown $!    # disown last pid
$ gdb          # invoke GDB

khi được gọi trên terminal theo thứ tự này, SIGINT không được truyền từ gdb sang openocd. Tuy nhiên, nếu lời gọi tương tự này nằm trong tập lệnh bash, SIGINT được thông qua.

Mọi sự trợ giúp sẽ rất được trân trọng.

Vấn đề này là ở OS X nhưng tôi đang cố gắng sử dụng các công cụ cũng có thể mang theo cho tất cả các công cụ Unix.


nohupkhông phải là câu trả lời đúng Bạn nên thêm một số mã giả hoặc mã ví dụ để hiển thị chính xác hơn những gì bạn muốn.
Bruce Ediger

1
Bạn có mở để sử dụng một công cụ như thế screennào?
Eric Renouf

Câu trả lời:


17

Để tách một quá trình từ tập lệnh bash:

nohup ./process &

Nếu bạn dừng tập lệnh bash của bạn bằng SIGINT(ctrl + c) hoặc shell thoát ra gửi SIGHUPchẳng hạn, quá trình sẽ không bị làm phiền và sẽ tiếp tục thực thi bình thường. stdout& stderrsẽ được chuyển hướng đến một tệp nhật ký : nohup.out.

Nếu bạn muốn thực thi một lệnh tách ra trong khi có thể thấy đầu ra trong thiết bị đầu cuối, thì hãy sử dụng tail:

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &

Tại sao cần thiết nohup? Sự khác biệt giữa nohup COMMAND &COMMAND &nếu mục tiêu của bạn chỉ là chạy lệnh trong nền và giải phóng thiết bị đầu cuối?
James Wierzba

@JamesWierzba Một trong những điểm khác biệt là nếu bạn cần lệnh để tiếp tục chạy ngay cả khi đã thoát khỏi shell, thì nohup là cách để đi. Có hàng ngàn lời giải thích trên web. Ví dụ: stackoverflow.com/questions/15595374/ hy
marc

10

Đối với tôi điều này hoạt động hoàn toàn tốt với disown

command & disown

4

Giải pháp tôi tìm thấy liên quan đến một chương trình gọi là 'tách ra' được viết bởi Annon Inglorion và có thể tải xuống từ trang web của anh ấy

Sau khi biên dịch, nó có thể được sử dụng trong một tập lệnh như sau:

$ ./detach -p debug.pid openocd <args> # detach openocd
$ gdb <args>                           # run gdb
$ kill -9 $(cat debug.pid)             # end openocd process
$ rm debug.pid                         # remove file containing process id

Dòng đầu tiên này tạo ra một quy trình mới (chạy openocd) và lưu trữ id quy trình trong tệp (debug.pid) để sử dụng sau. Điều này ngăn chặn các vấn đề với grepping cho pid như được cung cấp trong câu trả lời của Oliver. Khi thoát khỏi chương trình chặn tiếp theo (gdb), tệp lưu trữ pid được sử dụng để tiêu diệt trực tiếp quá trình tách rời.


Có thể xác nhận, detachlàm nên điều kỳ diệu.
NHƯ

2

một giải pháp đơn giản và di động:

echo "openocd" | at now #openocd starts now, but via the at daemon, not the current shell!
pid=$(ps -ef | grep "[o]penocd" | awk '{print $1}')  
echo "openocd is running with pid: $pid"
gdb

Một số lưu ý về tính di động: pscác tùy chọn phụ thuộc vào HĐH! thay vào đó bạn có thể sử dụng một biến thể của : { ps -ef || ps aux ;} | grep '[o]penocd | cut -f 1. atkhông thể có sẵn (kỳ lạ, nhưng điều này xảy ra ...). $(...)cần một vỏ cũ không thật, nếu không sử dụng backticks.


Điều này có vẻ nguy hiểm, grepping cho pid có thể làm những điều không mong muốn nếu có nhiều hơn một quy trình đang chạy cùng tên hoặc thậm chí, nếu một quy trình khác có chứa openocd.
orion

1
@orion: tôi đưa ra một ví dụ đơn giản để đưa ra ý tưởng, những mối quan tâm mà bạn đề cập rất dễ bị loại bỏ: đã atbắt đầu một kịch bản khởi chạy chương trình và đưa ra pid của nó thay vào đó trong một tệp và có kịch bản chính chờ điều đó tập tin xuất hiện và sau đó đọc pid từ nó.
Olivier Dulac

tất nhiên bạn nên thay thế trong ví dụ (quá đơn giản) của tôi grep bằng một bài kiểm tra bên trong awk, trên cột bên phải (thường là $ 8) (các cột phụ thuộc vào hệ điều hành và phiên bản / tùy chọn của ps)
Olivier Dulac
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.