$! не установлен в PID > >(…) подстановки процесса, используемой с внешней командой

Encontré una solución, muchas gracias a estas publicaciones:
https://stackoverflow.com/questions/37121895/yocto-build-loadlocale-c-130
Problema de No se puede establecer la configuración regional; ¡asegúrese de que $LC _*y $LANG sean correctos!

Sin embargo, todavía no estoy seguro de dónde echar la culpa de este problema.

Primero, para obtener una línea de comando utilizable, $LANGdebe definirse:

>$ LANG=/usr/lib/locale/en_US

(la configuración LANG=en_USNO funcionó, ¡se requiere la ruta!)

Luego, la línea de comando debería poder usarse nuevamente. Edite locale.gencomo raíz y elimine los comentarios de todas las configuraciones regionales que desee utilizar en su sistema:

>$ sudo vim /etc/locale.gen

Ahora ejecute locale-gencomo root y el sistema debería estar reparado.

La nota:dpkg-reconfigure localesno funcionó porque también arrojaba errores.


Para evitar este problema, elimine cmakeantes de actualizar (si está instalado )y actualice su sistema usando apt-get upgrade. No pude averiguar qué paquete necesitaría una actualización específica.

Pensé que actualizar localesdebería ser suficiente, pero eso no funcionó ya queapt-get upgrade locales(o los paquetes relacionados )dan como resultado un error de paquetes borken:

>$ sudo apt-get upgrade locales
[...]
The following packages have unmet dependencies:
 libc-dev-bin : Depends: libc6 (< 2.20) but 2.27-3 is to be installed
                Recommends: manpages-dev but it is not going to be installed
 libc6-dev : Depends: libc6 (= 2.19-18+deb8u10) but 2.27-3 is to be installed
E: Broken packages

y aunque creo que el paquete relevante es console-data(, ya que le preguntará amablemente qué diseño de teclado -le gustaría usar durante una actualización completa ), la actualización console-dataresultó en la actualización de los mismos paquetes como apt-get upgradese habría actualizado.

1
15.06.2019, 02:56
1 ответ

Если я вас правильно понимаю, вам интересно, почему $!будет установлен на PID процесса, запущенного внутри >(...), только если он является частью командной строки встроенной -в команде или функции., но не тогда, когда он является частью командной строки внешней команды.

Упрощенный пример:

$ bash -c 'true > >(echo in=$BASHPID; sleep.1); echo psubst=$!'
psubst=12392
in=12392

$ bash -c '/bin/true > >(echo in=$BASHPID; sleep.1); echo psubst=$!'
in=12751
psubst=

Это происходит потому, что в случае, когда используется внешняя команда, bashсоздаст отдельный процесс для ее запуска, а процесс, работающий внутри >(...), будет запущен как дочерний по отношению к этому процессу, и поэтому великое детище вашего сценария, полностью вне его контроля.

К моменту завершения внешней команды ее дочерний элемент (, если он все еще работает, )будет принят pid 1 (init ), и поэтому любая ссылка, которая все еще может использоваться для получения его PID из ваш скрипт сломан.

Обходной путь может заключаться в использовании функции-оболочки, которая заставит все подстановки процессов из ее командной строки выполняться как дочерние элементы вашего скрипта, поэтому их PID можно будет получить через pgrep -P "$$".

Кроме того, размещение внешней команды в блоке {...}и перенаправление вывода блока также работает:

$ bash -c 'func(){ /bin/true; }; func > >(echo in=$BASHPID; sleep.1); echo psubst=$!'
in=3574
psubst=3574
$  bash -c '{ /bin/true; } > >(echo in=$BASHPID; sleep.1); echo psubst=$!'
in=3435
psubst=3435

Оба обходных пути основаны на том, как работает текущая реализация; например. bashможет решить однажды оптимизировать тривиальные групповые команды или функции, нарушив эти предположения.

Обратите внимание, что установка $!на PID последней подстановки процесса является недокументированной функцией, которая также не работает в других оболочках, кроме bash.

4
27.01.2020, 23:17

Теги

Похожие вопросы