105 votes

Comment accéder à un répertoire avec la commande 'cd' s'il a une permission de 700 et ne m'appartient pas ?

J'ai essayé d'utiliser sudo cd name_of_dir mais je reçois le message d'erreur:

sudo: cd: command not found

Y a-t-il un autre moyen d'entrer dans un répertoire appartenant à un autre utilisateur qui a une permission de 700?

3voto

Eliah Kagan Points 111731

Si vous voulez vraiment que sudo cd _répertoire_ fonctionne, vous pouvez définir une fonction shell bash appelée sudo qui lance un nouveau shell root lorsque vous le lancez de cette manière, et qui exécute simplement la commande sudo normalement dans les autres cas.

Comme présenté dans d'autres réponses, la plupart des utilisateurs ne voudront probablement pas se donner la peine de le faire, mais voudront plutôt:

  1. Exécuter sudo -s, ou sudo -i pour obtenir un shell de connexion (rappelez-vous qu'un des effets de sudo -i est de vous placer dans le répertoire personnel de root), ou sudo bash si vous voulez forcer l'utilisation de bash ou pouvoir passer des options au shell.
  2. Exécuter cd _répertoire_ dans le nouveau shell.
  3. Effectuer toute (autre) action nécessitant des droits root dans le nouveau shell.
  4. Une fois terminé, exécuter exit pour quitter le nouveau shell. Il est important de ne pas oublier cela, car vous ne voulez pas exécuter plus d'actions en tant que root que ce que vous aviez prévu!

Ainsi, si vous le souhaitez, vous pouvez écrire une fonction shell (ou un script) qui effectue les deux premières actions lorsque sudo est suivi de cd, et qui exécute simplement sudo normalement dans les autres cas. Merci de ne pas utiliser cela comme une alternative pour comprendre pourquoi sudo cd ne fonctionne pas autrement, car si vous ne comprenez pas ce qui se passe, vous serez probablement très confus en étant dans un nouveau shell (et vous risquez de ne pas comprendre les messages d'erreur qui surviennent).

Voici une manière d'écrire une telle fonction shell, qui vous rappelle également que vous êtes dans un nouveau shell et que vous devez exécuter exit pour en sortir une fois que vous avez terminé. (Ce rappel risque d'être utile pour des utilisateurs de tous niveaux, car on n'a généralement pas l'habitude d'être dans un nouveau shell lorsqu'on exécute sudo sans -s, -i, ou le nom d'un shell réel comme argument.)

# Faire en sorte que sudo traite "sudo cd [RÉPERTOIRE]" comme un cas spécial et démarre un nouveau shell.
sudo() {
    if [ "$#" -eq 2 ] && [ "$1" = 'cd' ]; then
        sudo bash -c '
                if cd -- "$2"; then # Lorsque cd échoue, son propre message suffit.
                    printf "%s: Exécution de %s shell dans %s\n" "$0" "$USER" "$2" >&2
                    printf "%s: Tapez \"exit\" une fois que vous avez terminé!\n" "$0" >&2
                    exec bash # Remplacez ce shell bash par un shell interactif.
                fi
            ' bash _ "$2" # Utilisez $2 comme répertoire dans le shell intermédiaire, aussi.
    else
        command sudo "$@"
    fi
}

Vous pourriez mettre cela dans votre ~/.bashrc, bien que ce soit une manière suffisamment étrange d'utiliser sudo que vous voudrez peut-être l'activer occasionnellement seulement. Dans ce cas, il vaut mieux le mettre dans un fichier séparé. Si vous créez un fichier appelé sudo.bash dans votre répertoire personnel avec ce contenu, vous pouvez rendre la fonction sudo disponible - de sorte qu'elle s'exécute plutôt que la commande sudo normale - en exécutant . ~/sudo.bash. Cela prend effet dans le shell en cours et dans ses shells enfants, mais pas dans les autres. Pour la même raison pour laquelle des fichiers comme .bashrc ne sont pas exécutables, ne marquez pas sudo.bash comme exécutable avec chmod. Il s'agit en réalité davantage d'une bibliothèque que d'un script shell indépendant. Si vous le faisiez s'exécuter comme un script shell, il définirait la fonction ... mais seulement dans le shell qui a exécuté le script, et non pour vous en tant qu'appelant. (Bien sûr, vous pouvez écrire un script pour cela, mais ce n'est pas l'approche que j'ai choisie ici.)

Pour vérifier si sudo est actuellement défini comme une fonction shell, et pour voir sa définition actuelle s'il s'agit d'une fonction, exécutez type sudo. Pour désactiver (c'est-à-dire, annuler la définition) la fonction une fois qu'elle est définie, exécutez unset -f sudo. Pour exécuter manuellement la commande sudo normale directement même si la fonction shell est définie, exécutez command sudo. Notez cependant que vous n'êtes pas obligé de le faire, car cette fonction sudo le fait en fait d'elle-même chaque fois qu'il y a plus ou moins de deux arguments qui lui sont passés ou si le premier argument qui lui est passé n'est pas cd. C'est pourquoi vous pouvez toujours l'utiliser de la manière habituelle dont les gens utilisent sudo.

Notez également que la fonction shell mentionnée ci-dessus vous permet toujours de passer d'autres arguments à sudo, mais cela empêchera qu'elle traite cd de manière spéciale. En particulier, exécuter sudo -u **utilisateur** cd _répertoire_ n'est pas pris en charge, bien que vous pourriez étendre la fonction shell pour prendre en charge ce cas. Ni sudo -i cd _répertoire_. Le shell qu'elle crée est similaire à ce que vous obtenez avec sudo -s. Le code n'exécute pas réellement sudo -s, mais utilise sudo bash, donc l'option -c fonctionne correctement. Il exécute en fait bash deux fois lorsque vous lui passez cd et un argument de répertoire (et zéro fois autrement). Lorsque vous exécutez sudo cd _répertoire_, cela crée d'abord un shell bash distinct de celui où vous exécutez la fonction sudo et change de répertoire. Si cela réussit, il remplace ce shell bash par un nouveau, interactif que vous pouvez utiliser.

Voici un exemple de comment cette fonction shell "fait ce qu'il faut" automatiquement. Remarquez que sudo ls -A /root se comporte normalement. Ce n'est que lorsque j'essaie ensuite de cd vers un répertoire avec sudo qu'un nouveau shell est créé, et que je suis explicitement averti de ce qui se passe.

ek@Io:~$ sudo ls -A /root
[sudo] mot de passe pour ek:
.aptitude      .bashrc  .config  .emacs.d  .nano     .rpmdb
.bash_history  .cache   .dbus    .local    .profile
ek@Io:~$ sudo -k  # invalide mon horodatage actuel... comme si je partais pour un moment
ek@Io:~$ sudo cd /root/.local
[sudo] mot de passe pour ek:
bash: Exécution du shell root dans /root/.local
bash: Tapez "exit" une fois que vous avez terminé!
root@Io:/root/.local#
root@Io:/root/.local#
root@Io:/root/.local# exit
exit
ek@Io:~$

Si vous essayez de sudo cd vers un répertoire auquel vous ne pouvez même pas accéder en tant que root, vous obtiendrez simplement un message d'erreur:

ek@Io:~$ sudo cd /nonexistent
[sudo] mot de passe pour ek:
bash: ligne 1: cd: /nonexistent: Aucun fichier ou dossier de ce type
ek@Io:~$ sudo -k
ek@Io:~$ sudo cd /etc/crontab
[sudo] mot de passe pour ek:
bash: ligne 1: cd: /etc/crontab: Ce n'est pas un répertoire
ek@Io:~$

J'ai utilisé sudo -k entre les invocations dans les exemples ci-dessus pour montrer qu'il vous authentifie en tant que root avant de tenter de changer de répertoire. Mais vous n'êtes pas obligé d'exécuter sudo -k vous-même. Parce que la fonction shell est simplement une mince couche autour de la véritable commande sudo, la mise en cache de vos informations d'identification et autres comportements courants de sudo fonctionnent toujours normalement.

Même s'il fonctionne bien et est assez astucieux, j'admets que recouvrir la véritable commande sudo d'une fonction du même nom est assez bizarre. La plupart des utilisateurs voudront probablement simplement effectuer les étapes sudo -s, cd _répertoire_ eux-mêmes. Mais au cas où quelqu'un voudrait le faire - et aussi pour démontrer que c'est possible - le voici.

0voto

Joe Points 1759

En ce qui concerne le débat sur le su ou non, je pense que c'est absurde. Le su va à l'encontre de la religion d'Ubuntu et ce n'est pas quelque chose à faire négligemment. Il est incroyable ce qu'un rm -rf * peut faire si vous êtes root. Mais, si vous êtes à l'aise avec l'interface en ligne de commande (CLI) et que vous avez des tâches au niveau du système à effectuer, il n'y a aucune raison de ne pas utiliser su. J'ai utilisé plusieurs distributions où personne n'a même mentionné l'utilisation de sudo. C'est simplement une question du type de travail que vous effectuez et de la méthode avec laquelle vous êtes le plus à l'aise. J'utilise les deux.

0voto

flying_thorn Points 1

La solution de @Daniel Bauke fonctionne lorsque vous essayez de sudo une commande composée, telle que cd /some/path && ./executableScript.sh ce qui peut être ce dont vous avez besoin si executableScript.sh doit être exécuté depuis son répertoire, et nécessite sudo à la fois pour entrer dans le répertoire et pour exécuter le script (et que vous voulez faire cela de manière non interactive/session.

Pour réitérer, la solution de Daniel Bauke est :

sudo $SHELL -c "cd /some/path && ./executableScript.sh"

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X