libreria ejecutar desde consola compilar archivos python bash shell directory cd

compilar - ejecutar.py desde consola python



¿Cómo cambio mi directorio actual de un script python? (5)

Estoy tratando de implementar mi propia versión del comando ''cd'' que presenta al usuario una lista de directorios codificados para elegir, y el usuario tiene que ingresar un número correspondiente a una entrada en la lista. El programa, llamado my_cd.py por el momento, debe entonces ''cd'' efectivamente al usuario al directorio elegido. Ejemplo de cómo debería funcionar esto:

/some/directory $ my_cd.py 1) ~ 2) /bin/ 3) /usr Enter menu selection, or q to quit: 2 /bin $

Actualmente, estoy tratando de ''cd'' usando os.chdir(''dir'') . Sin embargo, esto no funciona, probablemente porque my_cd.py se inició en su propio proceso hijo. Traté de envolver la llamada a my_cd.py en un script bash de origen llamado my_cd.sh :

#! /bin/bash function my_cd() { /path/to/my_cd.py } /some/directory $ . my_cd.sh $ my_cd ... shows list of dirs, but doesn''t ''cd'' in the interactive shell

¿Alguna idea sobre cómo puedo hacer que esto funcione? ¿Es posible cambiar el directorio actual de mi shell interactivo desde un script de python?


Al contrario de lo que se dijo, puedes hacer esto reemplazando la imagen del proceso, dos veces.

En bash, reemplace su función my_cd con:

function my_cd() { exec /path/to/my_cd.py "$BASH" "$0" }

Entonces tu script python debe terminar con:

os.execl(sys.argv[1], sys.argv[2])

Recuerde import os, sys al comienzo del script.

Pero ten en cuenta que esto es un hack en el límite. Su caparazón muere, reemplazándose con el script de python, ejecutándose en el mismo proceso . El script python realiza cambios en el entorno y se reemplaza con el shell, nuevamente, aún en el mismo proceso. Esto significa que si tiene algún otro dato o entorno no guardado y no exportado local en la sesión de shell anterior, no se mantendrá en el nuevo. También significa que los scripts de rc y de perfil se ejecutarán nuevamente (generalmente no es un problema).


Cambie su código bash origen a:

#! /bin/bash function my_cd() { cd `/path/to/my_cd.py` }

y su código Python para hacer toda su salida cosmetic (mensajes a los usuarios, menús, etc.) en sys.stderr , y, al final, en lugar de os.chdir , simplemente print (en sys.stdout ) la ruta a la que el directorio debe ser cambiado.


Esto no se puede hacer. Los cambios en el directorio de trabajo no son visibles para los procesos principales. En el mejor de los casos, podría hacer que la secuencia de comandos de Python imprima el directorio para cambiar, y luego hacer que la secuencia de comandos de origen realmente cambie a ese directorio.


Por lo que vale, ya que esta pregunta también está etiquetada como "bash", aquí hay una solución simple bash-only:

$ cat select_cd #!/bin/bash PS3="Number: " dir_choices="/home/klittle /local_home/oracle" select CHOICE in $dir_choices; do break done [[ "$CHOICE" != "" ]] && eval ''cd ''$CHOICE

Ahora, esta secuencia de comandos debe ser fuente, no ejecutada:

$ pwd /home/klittle/bin $ source select_cd 1) /home/klittle 2) /local_home/oracle Number: 2 $ pwd /local_home/oracle

Asi que,

$ alias mycd=''source /home/klittle/bin/select_cd'' $ mycd 1) /home/klittle 2) /local_home/oracle Number:

Para resolver su caso, podría hacer que el comando que ejecuta el usuario sea un alias que ordene un script bash, que primero haga la selección de dir, luego se sumerja en un programa python después de que se haya realizado el cd.


my_cd.py :

#!/usr/bin/env python import sys dirs = [''/usr/bin'', ''/bin'', ''~''] for n, dir in enumerate(dirs): sys.stderr.write(''%d) %s/n'' % (n+1, dir)) sys.stderr.write(''Choice: '') n = int(raw_input()) print dirs[n-1]

Uso:

nosklo:/tmp$ alias mcd="cd /$(/path/to/my_cd.py)" nosklo:/tmp$ mcd 1) /usr/bin 2) /bin 3) ~ Choice: 1 nosklo:/usr/bin$