Si realmente desea hacer que funcione, puede definir una función de shell llamada que ejecuta un nuevo shell raíz cuando se ejecuta de esa manera, y simplemente ejecuta el comando regular de lo contrario.sudo cd directory
bash
sudo
sudo
Como se presenta en otras respuestas, la mayoría de los usuarios no querrán molestarse en hacer eso, sino que querrán:
- Ejecute
sudo -s
, o sudo -i
si desea un shell de inicio de sesión (recuerde que uno de los efectos sudo -i
es iniciarlo en el directorio de inicio de la raíz), o sudo bash
si desea forzar bash
o poder pasar opciones al shell.
- Ejecutar en el nuevo shell.
cd directory
- Realice cualquier (otra) acción que deba tomarse como raíz en el nuevo shell.
- Una vez hecho esto, corre
exit
para salir del nuevo shell. ¡Es importante no olvidar esto, porque no desea realizar más acciones como root de lo que pretende!
Por lo tanto, si lo desea, puede escribir una función de shell (o una secuencia de comandos) que realice las dos primeras de esas acciones cuando sudo
le siga cd
, y que de lo sudo
contrario se ejecuta normalmente. No utilice esto como una alternativa para aprender por qué sudo cd
no tiene éxito de otra manera , porque si no comprende lo que está sucediendo, es probable que se sienta muy confundido al estar en un nuevo shell (y es posible que no entienda ningún mensaje de error eso ocurre).
Aquí hay una forma de escribir dicha función de shell, que también le recuerda que está en un nuevo shell y que debe exit
salir de él cuando haya terminado. (Eso recordatorio es probable que sea útil para los usuarios de cualquier nivel de habilidad, ya que uno no es generalmente acostumbrado a estar en un nuevo shell cuando se corre sudo
sin -s
, -i
o el nombre de una cáscara real como un argumento.)
# Make sudo treat "sudo cd [DIRECTORY]" as a special case and start a shell.
sudo() {
if [ "$#" -eq 2 ] && [ "$1" = 'cd' ]; then
sudo bash -c '
if cd -- "$2"; then # When cd fails, its own message is enough.
printf "%s: Running %s shell in %s\n" "$0" "$USER" "$2" >&2
printf "%s: Type \"exit\" once you are done!\n" "$0" >&2
exec bash # Replace this bash shell with an interactive one.
fi
' bash _ "$2" # Use $2 as the dir in the intermediate shell, too.
else
command sudo "$@"
fi
}
Puede poner esto en su ~/.bashrc
, aunque esta es una forma lo suficientemente extraña de usar sudo
que es posible que solo desee habilitarlo ocasionalmente. En ese caso, es mejor ponerlo en su propio archivo. Si crea un archivo llamado sudo.bash
en su directorio de inicio con esos contenidos, puede hacer que la sudo
función esté disponible, para que se ejecute en lugar del sudo
comando normal , ejecutándose . ~/sudo.bash
. Eso tiene efecto en el caparazón actual y sus caparazones secundarios, pero no en otros. Por la misma razón por la que los archivos como .bashrc
no son ejecutables, no marque el sudo.bash
ejecutable con chmod
. Esto es realmente una biblioteca, en lugar de un script de shell independiente. Si lo hicierasejecutarlo como un script de shell, definiría la función ... pero solo en el shell que ejecutó el script, no para usted como la persona que llama. (Por supuesto, usted puede escribir un guión para esto, que simplemente no resultan ser el enfoque que he tomado aquí.)
Para verificar y ver si sudo
actualmente está definido como una función de shell, y para ver su definición actual si es una, ejecute type sudo
. Para deshabilitar (es decir, no definir) la función una vez que está definida, ejecute unset -f sudo
. Para ejecutar manualmente el sudo
comando regular directamente, incluso si la función de shell está definida, ejecute command sudo
. Sin embargo, tenga en cuenta que no tiene que hacer eso, porque esta sudo
función realmente lo hace por sí misma cada vez que se le pasan más o menos dos argumentos o el primer argumento que se le pasa es todo menos eso cd
. Es por eso que todavía puede usarlo de la manera normal que usan las personas sudo
.
Tenga en cuenta también que la función de shell que se muestra arriba todavía le permite pasar otros argumentos sudo
, pero eso evitará que se trate cd
especialmente . La ejecución en particular no es compatible, aunque podría ampliar la función de shell para admitir ese caso. Tampoco lo es . El shell que crea es similar a lo que obtienes . El código no se ejecuta realmente , sino que lo usa , por lo que la opción funciona correctamente. En realidad, se ejecuta dos veces cuando pasa y un argumento de directorio (de lo contrario, cero veces). Cuando ejecuta , primero se bifurca un shell bash separado del que está ejecutando la función y cambia el directorio. Si eso tiene éxito, reemplazasudo -u user cd directory
sudo -i cd directory
sudo -s
sudo -s
sudo bash
-c
bash
cd
sudo cd directory
sudo
ese bash shell con uno nuevo e interactivo que puedes usar.
Aquí hay un ejemplo de cómo ese shell funciona automáticamente "hace lo correcto". Tenga en cuenta que se sudo ls -A /root
comporta normalmente. Solo cuando intento acceder cd
a un directorio con sudo
se crea un nuevo shell y se me recuerda explícitamente lo que está sucediendo.
ek@Io:~$ sudo ls -A /root
[sudo] password for ek:
.aptitude .bashrc .config .emacs.d .nano .rpmdb
.bash_history .cache .dbus .local .profile
ek@Io:~$ sudo -k # invalidates my current timestamp... like I left for a while
ek@Io:~$ sudo cd /root/.local
[sudo] password for ek:
bash: Running root shell in /root/.local
bash: Type "exit" once you are done!
root@Io:/root/.local#
root@Io:/root/.local#
root@Io:/root/.local# exit
exit
ek@Io:~$
Si intenta sudo cd
acceder a un directorio que no puede cambiar incluso como root, recibirá un mensaje de error:
ek@Io:~$ sudo cd /nonexistent
[sudo] password for ek:
bash: line 1: cd: /nonexistent: No such file or directory
ek@Io:~$ sudo -k
ek@Io:~$ sudo cd /etc/crontab
[sudo] password for ek:
bash: line 1: cd: /etc/crontab: Not a directory
ek@Io:~$
He utilizado sudo -k
entre invocaciones en los ejemplos anteriores para mostrar que lo autentica como root antes de intentar cambiar el directorio. Pero en realidad no tienes que correr sudo -k
tú mismo. Debido a que la función de shell es solo una envoltura delgada para el sudo
comando real , el almacenamiento en caché de sus credenciales y otros sudo
comportamientos comunes todavía funcionan normalmente.
Aunque funciona bien y es bastante ordenado, admito que sombrear el sudo
comando real con una función del mismo nombre es muy extraño. La mayoría de los usuarios probablemente sólo quieren llevar a cabo los pasos sudo -s
, a sí mismos. Pero en caso de que alguien quiera esto, y también para demostrar que es posible, ahí está.cd directory
ls -l
del directorio en sí.