Trong zsh, làm thế nào tôi có thể nhanh chóng từ chối quá trình tiền cảnh hơn?


7

Phương pháp của tôi để từ chối quá trình tiền cảnh mất quá nhiều nỗ lực.

Giả sử tôi có một quá trình ở zshtiền cảnh. Tôi muốn disownnó, vì vậy tôi có thể đóng vỏ mà không cần quá trình được gửi a SIGHUP.

Hiện tại, tôi bắt đầu với Ctrl+ zđể làm nền và tạm dừng quá trình, sau đó

$ disown
disown: warning: job is suspended, use `kill -CONT -32240' to resume
$ kill -CONT -32240
$

- sau đó tôi có thể đóng thiết bị đầu cuối.

Làm thế nào tôi có thể tự động hóa điều đó? Lý tưởng nhất là tôi muốn có thể nhấn Ctrl+ jhoặc một cái gì đó để từ chối ngay lập tức quá trình đang chạy. Hoặc tốt nhất thứ hai, tôi muốn có thể chạy một lệnh duy nhất cho cả hai từ chối và SIGCONTquá trình một khi nó bị treo.


4
Nó dễ dàng hơn bg+ disownthay vì kill -CONT -1234.
jimmij

Tôi đã từng sử dụng alias dr='disown -r'trong bash. bgdrthực hiện các mẹo.
Peter Cordes

Câu trả lời:


11

Có một keybind toàn cầu để từ chối quá trình foreground là không thể: Keystrokes được nhận bởi quá trình foreground, không phải bởi shell. Trước tiên bạn cần tạm dừng nó với Ctrl+ znếu bạn muốn từ chối nó.

Tuy nhiên, hóa ra có một tùy chọn zsh để tăng tốc độ từ chối sau đó tiếp tục : Với setopt AUTO_CONTINUE, disowncũng sẽ tự động gửi SIGCONT.

Vì vậy, bạn có thể nhận được nó xuống C-z disown.


11

Khi bạn nhấn Ctrl+ Ztrong một thiết bị đầu cuối, điều này làm cho nhóm quy trình nền trước nhận được tín hiệu SIGTSTP (giả sử thiết bị đầu cuối ở chế độ nấu và có các ràng buộc phím mặc định). Nếu quy trình không đặt trình xử lý tín hiệu cho SIGTSTP, điều này khiến quá trình bị đình chỉ (và ngay cả khi quy trình đã đặt trình xử lý tín hiệu, nó thường chỉ thực hiện một lượng nhỏ xử lý trước khi tạm dừng). Khi một quá trình bị giết, bị đình chỉ hoặc được nối lại, cha mẹ của nó được thông báo qua tín hiệu SIGCHLD; đây là nguyên nhân khiến shell hiển thị một dấu nhắc mới và có thể là một thông báo như thế nào [1] + 1234 suspended foo. Luồng thông tin là
    khóa → hệ thống treo → vỏ
và không phải
    khóa → vỏ → hệ thống treo
để bạn không thể định cấu hình phản ứng khác cho Ctrl+ Z.

Bạn có thể đặt bẫy cho SIGCHLD, nhưng bẫy không được thực thi khi công việc là công việc tiền cảnh hiện tại. Đối với hầu hết các phần, điều này có nghĩa là bẫy chỉ được thực hiện khi một công việc nền kết thúc, chứ không phải khi công việc nền trước kết thúc. Nhưng nó cũng có nghĩa là bạn không thể phản ứng với việc đình chỉ công việc tiền cảnh.

Bạn có thể gián tiếp phản ứng với những thay đổi trong công việc nền bằng cách đặt precmdmóc so sánh trạng thái công việc với trạng thái được lưu từ lần precmdchạy trước . Nhưng tôi không biết bạn có thể làm gì với điều đó: chỉ có thể có một khóa tạm dừng duy nhất, vì vậy bạn cần thêm một số thông tin để biết liệu quy trình này có nghĩa là tạm dừng, nền hoặc từ chối.

Tôi đã thiết lập zsh để nhấn Ctrl+ Ztại một dấu nhắc trống nền công việc hiện tại. Điều này cho phép tôi nhấn Ctrl+ Zhai lần để đặt công việc nền trước vào nền chỉ với một hệ thống treo ngắn.

fancy-ctrl-z () {
  if [[ $#BUFFER -eq 0 ]]; then
    bg
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z

Bạn có thể làm cho nó gọi disownnếu bạn muốn. Hoặc bạn có thể sắp xếp cho một phần ba Ctrl+ Zđể gọi disownvới sửa đổi chưa được kiểm tra sau đây.

fancy-ctrl-z () {
  if [[ $#BUFFER -eq 0 ]]; then
    if (($fancy_ctrl_z_already_bg)); then
      disown
    else
      bg
      fancy_ctrl_z_already_bg=1
    fi
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z
fancy_ctrl_z_precmd () {
  fancy_ctrl_z_already_bg=0
}
precmd_functions+=fancy_ctrl_z_precmd

Lưu ý rằng bạn không cần chế độ nấu đầy đủ để ^ Z hoạt động. isiglà đủ (thậm chí không có icanon)
Stéphane Chazelas

Vì vậy, SIGTSTPđược gửi bởi trình giả lập thiết bị đầu cuối? Có thể định cấu hình trình giả lập (bất kỳ cái gì bạn biết) để thay đổi những gì nó làm cho một ^Z? Giống như trong các ưu tiên phím tắt?
Franklin Yu

@FranklinYu Trình giả lập thiết bị đầu cuối gửi SIGTSTP khi bạn nhấn Ctrl + Z trong khi chương trình đang chạy và tính năng được kích hoạt trong giao diện đầu cuối ( stty +isig). Bạn có thể thay đổi ký tự nào kích hoạt điều này bằng lệnh stty (bạn không thể đặt một khóa tùy ý, nó phải là một byte đơn, không phải là một chuỗi thoát). Trong khi shell nằm ở phía trước, nó sẽ thay đổi cài đặt đầu cuối để tiếp tục nhấn phím, do đó, hiệu ứng của Ctrl + Z phụ thuộc vào các ràng buộc phím của shell.
Gilles 'SO- ngừng trở nên xấu xa'
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.