El problema es iniciar un trabajo en segundo plano desde una trampa. El trabajo parece "perderse" a veces. Cambiar vim
a vim &
hace que el trabajo se retenga a veces, por lo que puede haber una condición de carrera.
Puede evitar esto si no inicia el trabajo desde una trampa. Coloque una bandera en la trampa y encienda vim fuera de la trampa, en el gancho precmd
. Aquí hay una adaptación de su ejemplo mínimo.
restart_vim=
catch_signal_usr1() {
trap catch_signal_usr1 USR1
restart_vim=1
}
precmd () {
if [[ -n $restart_vim ]]; then
restart_vim=
vim
fi
}
trap catch_signal_usr1 USR1
func() {
vim
}
Pierde la capacidad de mostrar Vim en primer plano mientras edita un símbolo del sistema, pero eso no funciona de todos modos, ya que vim y zsh estarían compitiendo por la terminal.
En su código real, puede tener problemas porque está iniciando vim desde una subcapa. No ejecute la función nv
en una subcapa :use llaves { … } around the body, not parentheses. Use
IFS local to make the
IFS `variable local.
Отличие заключается в создании двух каналов ввода-вывода, как описано в man bash
:
A coprocess is executed asynchronously in a subshell, as if the command had been terminated with the & control operator, with a two-way pipe established between the executing shell and the coprocess.
coproc utility
не совпадает с utility &
в bash
.
С помощью coproc utility
вы получаете массив COPROC
, который содержит стандартные входные и выходные файловые дескрипторы utility
. Затем вы можете делать такие вещи, как
#!/bin/bash
coproc bc -l
for (( k = 0; k < 50; ++k )); do
printf '2.3*%d + 1\n' "$k" >&${COPROC[1]}
read -u "${COPROC[0]}" a
printf '%.2f\n' "$a"
done
kill "$COPROC_PID"
Здесь bc -l
является со-процессом и действует как «служба арифметических вычислений» для цикла оболочки, принимая выражения для вычисления на своем стандартном вводе и возвращая результаты на своем стандартном выходе.
Насколько я могу судить, bash
также поддерживает только один со-процесс в любой момент времени.
Оболочка ksh93
также поддерживает процессы -co, но синтаксис совершенно другой (, но несколько изящнее ). Это эквивалентный скрипт ksh93
:
#!/usr/bin/ksh93
bc -l |&
coproc_pid=$!
for (( k = 0; k < 50; ++k )); do
print -p -f '2.3*%d + 1\n' "$k"
read -p a
printf '%.2f\n' "$a"
done
kill "$coproc_pid"
Здесь это опция -p
для print
и read
, которая заставляет его взаимодействовать с со -процессом (, который начался с |&
), а не использовать какой-то явный файловый дескриптор.