linux - una - ¿Cómo configuro el directorio de trabajo del proceso padre?
dar permisos a un usuario especifico en linux (7)
¿Cómo podría cambiar exactamente el directorio de trabajo de bash (o padre en general)?
No es posible utilizando ninguna forma "aceptable". Por aceptable, me refiero a "sin piratear de forma escandalosa su sistema (usando gdb por ejemplo)";)
Más seriamente, cuando el usuario inicia un ejecutable, el proceso secundario se ejecutará en su propio entorno, que es principalmente una copia de su entorno principal. Este entorno contiene "variables de entorno" así como el "directorio de trabajo actual", solo para nombrar esas dos.
Por supuesto, un proceso puede alterar su propio entorno. Por ejemplo, para cambiar su directorio de trabajo (como cuando cd xxx
en tu shell). Pero dado que este entorno es una copia , eso no altera el entorno del padre de ninguna manera. Y no hay una manera estándar de modificar su entorno principal.
cd
("chdir") es un comando de shell interno , y no una utilidad externa . Si ese fuera el caso, no podría cambiar el directorio de trabajo del shell. A medida que el título lo revela, estamos escribiendo una utilidad de shell de estilo Unix que se supone que debe invocarse (en la mayoría de los casos) desde bash.
¿Cómo podría U cambiar exactamente el directorio de trabajo de bash (o padre en general)?
PS La utilidad de shell chdir tiene éxito en hacer exactamente lo mismo, por lo tanto, debe haber una forma programática de lograr el efecto.
El comando chdir es un shell incorporado, por lo que tiene acceso directo al directorio de trabajo del shell que lo ejecuta. Los shells suelen ser muy buenos para protegerse de los efectos de los scripts, lo que le da al niño el procesamiento de una copia del propio entorno de trabajo del shell. Cuando el proceso hijo se cierra, el entorno que utiliza se elimina.
Una cosa que puedes hacer es ''fuente'' de un script. Esto le permite cambiar el directorio porque, en esencia, le está diciendo al shell que ejecute los comandos del archivo como si los hubiera escrito directamente. Es decir, no estás trabajando desde una copia del entorno de la shell, estás trabajando directamente en él, cuando realizas el suministro.
En caso de que esté ejecutando el shell de manera interactiva y el directorio de destino sea estático, simplemente puede poner un alias en su archivo ~/.bashrc
:
alias cdfoo=''cd theFooDir''
Al tratar con scripts de shell no interactivos, puede crear un protocolo entre el script de Bash parental y el script de Bash secundario. Un método para implementar esto es dejar que la secuencia de comandos secundaria guarde la ruta en un archivo (como ~/.new-work-dir
). Una vez que finaliza el proceso hijo, el proceso parental deberá leer este archivo (como cd `cat ~/.new-work-dir`
).
Si planea usar la regla mencionada en el párrafo anterior muy a menudo, le sugeriría que descargue el código fuente de Bash y lo modifique para que cambie automáticamente el directorio de trabajo al contenido de ~/.new-work-dir
cada vez que lo haga. ejecuta un comando. En el parche, incluso podría implementar un comando incorporado completamente nuevo de Bash que se adapte a sus necesidades e implemente el protocolo que desea implementar (este nuevo comando probablemente no será aceptado por los mantenedores de Bash). Pero, el parcheo funciona para uso personal y para uso en una comunidad más pequeña.
La forma en que resolví esto es tener un alias de shell que llame al script y genere un archivo que escribió el script. Así, por ejemplo,
function waypoint {
python "$WAYPOINT_DIRECTORY"/waypoint.py $@ &&
source ~/.config/waypoint/scratch.sh
cat /dev/null > ~/.config/waypoint/scratch.sh
}
y waypoint.py
crea scratch.sh
para que parezca
cd /some/directory
Esto sigue siendo una cosa mala.
No estoy seguro si es un " no hagas esto " también ...
Gracias a la discusión extremadamente útil en https://unix.stackexchange.com/questions/213799/can-bash-write-to-its-own-input-stream/ ...
La utilidad tailcd
(para "tail-call cd
") que funciona tanto en bash como en Midnight Commander permite su uso en scripts como
/ bin / mkcd:
mkdir "$1" && tailcd "$1"
La implementación es complicada y requiere xdotool
. El comando tailcd
debe ser el último comando en el script (este es un requisito típico de compatibilidad para las utilidades que permiten implementaciones múltiples). Hackea el flujo de entrada de bash, es decir, inserta cd <dirname>
en él. En el caso de Midnight Commander, además inserta dos comandos de teclado Ctrl + O (paneles activados / desactivados) y, de una manera muy complicada, usa el modo de espera para la sincronización entre procesos (lo que es una vergüenza, pero funciona).
/ bin / tailcd:
#! /bin/bash
escapedname=`sed ''s/[^a-zA-Z/d._/-]/////&/g'' <<< "$1"`
if [ -z "$MC_TMPDIR" ] ; then
xdotool type " cd $escapedname "; xdotool key space Return
else
(sleep 0.1; xdotool type " cd $escapedname "; xdotool key space Return Ctrl+o; sleep 0.1; xdotool key Ctrl+o )&
fi
(El espacio antes de cd
impide que el comando insertado vaya al historial; los espacios después del nombre del directorio son necesarios para que funcione, pero no sé por qué).
Otra implementación de tailcd
no usa xdotool
, pero no funciona con Midnight Commander:
#!/bin/bash
escapedname=`sed ''s/[^a-zA-Z/d._/-]/////&/g'' <<< "$1"`
perl -e ''ioctl(STDIN, 0x5412, $_) for split "", join " ", @ARGV'' " cd" "$escapedname" $''/r''
Idealmente, tailcd
sería / debería ser una parte de bash, utilizar una comunicación normal entre procesos, etc.
No existe una manera "legal" de influir en el directorio actual del proceso principal, sino simplemente pedirle al proceso principal que lo cambie.
chdir
que cambia el directorio en scripts bash no es una utilidad externa, es un comando incorporado.
No hagas esto
FILE *p;
char cmd[32];
p = fopen("/tmp/gdb_cmds", "w");
fprintf(p, "call chdir(/"../")/ndetach/nquit/n");
fclose(p);
sprintf(cmd, "gdb -p %d -batch -x /tmp/gdb_cmds", getppid());
system(cmd);
Probablemente funcionará, aunque tenga en cuenta que el comando pwd
de Bash está en caché y no se dará cuenta.