Ejecutar scripts desde otro directorio

11

Muy a menudo, el script que quiero ejecutar no se encuentra en mi directorio de trabajo actual y realmente no quiero dejarlo.

¿Es una buena práctica ejecutar scripts (BASH, Perl, etc.) desde otro directorio? ¿Por lo general encontrarán todas las cosas que necesitan para funcionar correctamente?

Si es así, ¿cuál es la mejor manera de ejecutar un script "distante"? Lo es

. /path/to/script

o

sh /path/to/script

y como usar sudoen tales casos? Esto, por ejemplo, no funciona:

sudo . /path/to/script
Desmond Hume
fuente
Tenga en cuenta que las . /path/to/script fuentes del guión! No necesita el período en absoluto si solo desea ejecutarlo.
gniourf_gniourf

Respuestas:

14

sh / path / to / script generará un nuevo shell y ejecutará un script independiente de su shell actual. El sourcecomando (.) Llamará a todos los comandos del script en el shell actual. Si el script llama, exitpor ejemplo, perderá el shell actual. Debido a esto, generalmente es más seguro llamar scripts en un shell separado con sh o ejecutarlos como archivos binarios usando la ruta completa (comenzando con /) o relativa (./). Si se llama como binarios, se ejecutarán con el intérprete especificado (#! / Bin / bash, por ejemplo).

En cuanto a saber si un script encontrará o no los archivos que necesita, no hay una buena respuesta, aparte de mirar el script para ver qué hace. Como opción, siempre puede ir a la carpeta del script en un subproceso sin salir de su carpeta actual:

$(cd /wherever/ ; sh script.sh)
Ярослав Рахматуллин
fuente
3
Qué quiere decir (cd /wherever/ ; sh script.sh)? ¿Por qué tienes un $frente?
G-Man dice 'Restablecer a Monica'
7

Definitivamente puedes hacer eso (con los ajustes que los otros mencionaron como sudo sh /pathto/script.sho ./script.sh). Sin embargo, hago una de las pocas cosas para ejecutarlos en todo el sistema para no preocuparme por los directorios y ahorrarme tipeo adicional inútil.

1) Enlace simbólico a /usr/bin

ln -s /home/username/Scripts/name.sh /usr/bin/name

(asegúrese de que no haya nombres superpuestos allí, porque obviamente lo anularía). Esto también me permite mantenerlos en mis carpetas de desarrollo para que pueda ajustarlos según sea necesario.

2) Agregue el directorio Scripts a su ruta (usando .bash_profile - o lo que sea. Perfil que tiene en su shell)

PATH=/path/to/scripts/:$PATH

3) Crear alias en el complemento .bash_profile de ~/.bash_profileagregar algo como:

alias l="ls -l"

Como puede ver, la sintaxis es solo un alias, dígitos que desea que actúen como un comando, el comando. Por lo tanto, escribir "l" en cualquier lugar del terminal daría como resultado ls -l Si desea sudo, solo alias sl="sudo ls -l"para tener en cuenta l vs sl (como un ejemplo inútil).

De cualquier manera, puede escribir sudo nameofscripty seguir su camino. No es necesario meterse con ./ o. o sh, etc. Simplemente márquelos como ejecutables primero: D

nerdwaller
fuente
Recomiendo encarecidamente la opción 2.
Bernhard
¿Por qué ?, ¿es una mejor práctica o simplemente un gusto?
Sergio
3

Usualmente me gusta como dices

sh /path/to/script

Y para ejecutarlo como root / superusuario

sudo sh /path/to/script

Su directorio actual solo importa si los scripts asumen que está en la misma carpeta que él. Supongo que la mayoría de los scripts no hacen esto y está guardado para ejecutarlo como se indica arriba.

Bolli
fuente
no funcionaría si secure_path está configurado en el archivo / etc / sudoers
l1zard
3

Usualmente mantengo mis scripts en /usr/local/bino /usr/local/sbin/(si el script necesita privilegios de root) donde, de acuerdo con el Estándar de Jerarquía del Sistema de Archivos (FHS), pertenecen.

Todo lo que tiene que hacer es asegurarse de que estos dos directorios se agreguen a su PATH. Puede hacer esto editando su $HOME/.bashrcarchivo y agregando esta línea:

export PATH=$PATH:/usr/local/sbin:/usr/local/bin

Si desea poder ejecutar un script como root vía sudo, debe agregar estos directorios a la variable secure_pathen su /etc/sudoers.

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

La edición de este archivo se realiza ejecutando, lo visudoque garantiza que no tenga ningún error.

l1zard
fuente
Error tipográfico: quieres decir en .bashrclugar de .bachrc.
gniourf_gniourf
0

No estoy seguro de que funcione así en Linux, suponiendo que no lo haga si nadie lo sugirió. Pero en lugar de usar ././ para volver a los directorios. ¿Puedes usar comillas para darle un camino absoluto? Tal vez no le da acceso a todo el disco para poder incluso hacer eso.

Codezilla
fuente
0

Si tiene scripts que necesita ejecutar con frecuencia, y dependen de su ubicación para encontrar recursos, puede hacerlo fácilmente combinando comandos en un alias como este.

alias run-script="cd /home/user/path/to/script/ && bash script.sh"

De esta manera, no tiene que alterar nada más para que funcione.

EvR2f
fuente
0

No estoy seguro de por qué nadie ha sugerido este, ¡pero es súper fácil! He buscado en Google varias veces y no pude encontrar esta respuesta exacta que estoy dando, así que pensé en compartir. OMI, esta pero la mejor solución, también la más fácil, para mí de todos modos, sin embargo, otros pueden sentir y hacer las cosas de manera diferente.

# Place this somewhere in your .bashrc/.bash_profile/etc and edit as you see fit

YOURCOMMAND () {
  cd /path/to/directory/containing/your/script/ && ./YOURSCRIPT
}

Primero el comando 'cd' que le dice el directorio de la ubicación de los scripts. Luego '&&' para que pueda vincularlo después de excitar el siguiente comando. ¡Finalmente abra su script tal como lo ejecutaría dentro de la terminal! Guarda tu archivo BASH y tarda 5 segundos en configurarse.

Espero que esto haya ayudado a alguien.

AnónimoX
fuente
-1

Antigua pregunta, pero atemporal.

La solución que he visto consistentemente es tener un $HOME/bindirectorio y ponerlo primero $PATH(a través de ~/.bashrcsi aún no está allí; en algunos sistemas ~/binestá primero en $PATHforma predeterminada). Colocar scripts allí para su ejecución o enlaces simbólicos a scripts / ejecutables en otra parte es la forma más sencilla de lidiar con problemas de ruta que no deberían afectar al sistema ni a otros usuarios.

Si una secuencia de comandos requiere recursos adicionales que se pueden encontrar en relación con su propia ubicación (no es raro), $BASH_SOURCEse utiliza el envvar . $BASH_SOURCEsiempre contiene la ruta absoluta al script actualmente en ejecución, independientemente del valor de $PWD.

Considera lo siguiente:

ceverett@burrito:~$ echo $PATH
/home/ceverett/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Entonces podemos ver que $HOME/bines el primero en $PATHentrar, así que todo lo que ponga ~/binse ejecutará. Tengo un script de demostración llamado ~/bin/findme:

#!/bin/bash

echo "Running from $BASH_SOURCE"

Esto se puede usar para obtener la ruta absoluta a la ubicación del script en ejecución.

ceverett@burrito:~$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~$ cd foo
ceverett@burrito:~/foo$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~/foo$ cd /
ceverett@burrito:/$ findme
Running from /home/ceverett/bin/findme
zxq9
fuente
(1) Si bien esto parece ser información útil, la pregunta no fue cómo escribir guiones que utilicen recursos en relación con su propia ubicación; preguntó sobre la ejecución de scripts. (2) No estoy seguro de cómo su segundo párrafo aborda la pregunta. ¿Está sugiriendo que, si escribo un script y Desmond quiere ejecutarlo, debería vincularlo a su bindirectorio privado ? Eso parece engorroso. (3) Además, rompe la independencia de la ubicación. Si /home/desmond/bin/fooes un enlace a mi script, entonces BASH_SOURCElo será /home/desmond/bin/foo, y el script no podrá encontrar sus recursos.
G-Man dice 'Reincorporar a Monica'
@ G-Man (1) El usuario no proporcionó mucho contexto. Cada vez que me han hecho esta pregunta en los últimos 30 años, siempre ha sido en el contexto de un usuario (generalmente un nuevo sysop o desarrollador) que ejecuta una mezcla de sus propios y otros scripts adquiridos para automatizar tareas triviales, así que respondí que camino. Esto hace suponer un poco de conocimiento de secuencias de comandos por parte del usuario que pide. (2) Los scripts de todo el sistema generalmente se instalan en /bino en una ubicación conocida /opt. (3) La independencia de ubicación es exactamente lo que esto conserva al escribir una colección interdependiente de guiones personales.
zxq9