He creado un programa C simple así:
int main(int argc, char *argv[]) {
if (argc != 5) {
fputs("Not enough arguments!\n", stderr);
exit(EXIT_FAILURE);
}
Y tengo mi RUTA modificada en etc / bash.bashrc así:
PATH=.:$PATH
He guardado este programa como set.c y lo estoy compilando con
gcc -o set set.c
en la carpeta
~/Programming/so
Sin embargo, cuando llamo
set 2 3
no pasa nada. No hay texto que aparezca.
Vocación
./set 2 3
da el resultado esperado
Nunca he tenido un problema con PATH antes y
which set
vuelve ./set
. Entonces parece que la RUTA es la correcta. ¿Qué está pasando?
shell
path
shell-builtin
Ganea Dan Andrei
fuente
fuente
test
básicamente por la misma razón;test
También es un shell incorporado.test
parece tener sentido. Por supuesto, para cuando lo coloques en tuPATH
realmente deberías haber encontrado un nombre diferente. Y hasta que ponga el programa en suPATH
cuenta, deberá invocarlo como de./test
todos modos. Por lo tanto, está bien usar el nombretest
de un programa siempre que sea una prueba rápida que intente eliminar antes de que finalice el día.foo
.ls
cada vez que vaya a ver si existe, se ejecutará (pero solo si modifica su ruta como lo hizo en la pregunta).Respuestas:
En lugar de usar
which
, que no funciona cuando más lo necesita , usetype
para determinar qué se ejecutará cuando escriba un comando:El shell siempre busca incorporaciones antes de buscar
$PATH
, por lo que la configuración$PATH
no ayuda aquí.Sería mejor cambiar el nombre de su ejecutable a otra cosa, pero si su asignación requiere que se nombre el programa
set
, puede usar una función de shell:(Eso funciona
bash
, pero otros shells comoksh
pueden no permitirlo. Vea la respuesta de mikeserv para una solución más portátil).Ahora escribiendo
set
se ejecutará la función llamada "set", que se ejecuta./set
. GNUbash
busca funciones antes de buscar builtins, y busca builtins antes de buscar el$PATH
. La sección denominada "EJECUCIÓN DE MANDOS" en la página del manual de bash brinda más información al respecto.Consulte también la documentación sobre
builtin
ycommand
:help builtin
yhelp command
.fuente
type
máswhich
, pero no des ninguna razón por qué. ( Sé por qué , pero alguien que necesita la recomendación no lo haría.)type
lugar dewhich
, no asigne un nombre a su programa "set", y comprenda quefunction set { ./set; }
es un truco feo que probablemente debería evitar.set
es un incorporado en bash (y probablemente en la mayoría de las otras conchas). Esto significa que bash ni siquiera buscará la ruta cuando busque la función.Como comentario adicional, recomendaría encarecidamente no agregar
.
al camino por razones de seguridad. Imagine, por ejemplocd
, salir/tmp
después de que cualquier otro usuario agregue un archivo ejecutable/tmp/cd
.fuente
cd
es un shell incorporado, por lo que el ejemplo no funcionará por la misma razón que conset
../foo
para invocar un programa es profesional; muestra que entiendes por.
qué no debería estar en $ PATH. Tu maestro está equivocado, y puedes decirle que lo dije.set
no es solo una construcción integrada, es una construcción especial POSIX . Hay algunas órdenes internas que son estándares especificados que se encuentran en una búsqueda de comandos antes de cualquier otra cosa -$PATH
no se busca, nombres de funciones no se buscan, y etc. La mayoría de las órdenes internas que son no especiales están realmente requerido por el estándar POSIX sean encontrado en su$PATH
antes de que el shell ejecute cualquiera de sus propios procedimientos integrados. Este es el caso deecho
y la mayoría de los demás (aunque si la norma es honrado en este sentido ha sido un tema de discusión en las listas de correo de grupo abierto en el pasado) , pero no deset
,trap
,break
,return
,continue
,.
,:
,times
,eval
,exit
,export
,readonly
,unset
, Oexec
.Todos estos son nombres reservados del shell, y también tienen atributos especiales además de su orden de preferencia para la búsqueda de comandos. Por ejemplo, no puede definir una función de shell con ninguno de esos nombres en un shell compatible con los estándares. Esto es algo bueno : permite a las personas escribir scripts portátiles de forma segura . Estos son comandos de línea de base desde los cuales un escritor de guiones experimentado puede establecer un punto de apoyo seguro y confiable en su entorno. Invadir este espacio de nombres no es aconsejable.
Sin embargo, si desea invadirlo, puede hacerlo de forma portátil
alias
. El orden de expansión de shell permite esta solución. Debido a quealias
se expande mientras se lee el comando, lo que sea que reemplace elset
nombre en su definición se expandirá correctamente, probablemente no debería expandirse a uno de esos nombres.Entonces podrías hacer:
... que funcionará bien.
fuente
El problema es que
set
es un shell integrado y la mejor solución sería usar un nombre diferente para su programa ejecutable.Por cierto, la semana pasada, hice una pregunta sobre cómo ejecutar los comandos del sistema en lugar de los shell incorporados con el mismo nombre y la solución que acepté fue ejecutar el comando a través de
env
:Para este caso en particular, donde ya sabe que el comando que desea usar se encuentra en su directorio actual, sería mejor ejecutar directamente el ejecutable ingresando su ruta (usando
.
para representar el directorio de trabajo actual):Ambas soluciones anteriores son independientes de la shell, es decir, funcionarán independientemente de la shell que esté utilizando.
Sugerencias como el uso de la función
command
integrada no funcionarán en Bash: esto solo evita que se ejecuten las funciones de shell . Si bien no está documentado, también he notado que el usocommand
también suprime las palabras clave de shell . Sin embargo, no hará lo mismo para las construcciones de shell comoset
. Según tengo entendido,command
puede funcionar con otros shells como zsh.Además, trucos tales como
\set
o"set"
, o'set'
no lo hacen el trabajo de órdenes internas del golpe - a pesar de que son útiles para la ejecución de archivos ejecutables en lugar de alias o de concha palabras clave .Nota: Esta respuesta originalmente comenzó como un comentario sobre la respuesta (aceptada) de Eric, pero se hizo demasiado grande para caber en un comentario. Las otras respuestas que recomiendan usar
type
y no agregar.
a la RUTA son buenas.fuente