Ubuntu 17.04 - bash: cd: trop d'arguments

10

Je viens de mettre à jour mon Ubuntu 16.04 vers 17.04 et j'ai trouvé un petit problème avec la cdcommande.

Disons que j'ai deux dossiers: album-01&album-02

Dans Ubuntu 16.04, si je le fais, cd album*il ira dans le premier dossier trouvéalbum-01

Mais dans le nouveau Ubuntu 17.04, si je le fais, cd album*cela me -bash: cd: too many arguments

Comment faire cddans Ubuntu 17.04 comme cddans Ubuntu 16.04?

Hidayats
la source
4
Ce que vous obtenez a du sens, car vous donnez cddeux emplacements, et attendez-vous à ce qu'il trouve celui que vous voulez.
mikewwhat
1
@mikewwhat Malheureusement, le manuel de Bash n'est pas d'accord avec vous: "Tout argument supplémentaire suivant le répertoire est ignoré"
muru
3
Publié un rapport de bogue, au cas où quelqu'un serait
muru
N'oubliez pas d'accepter la réponse qui vous a le plus aidé en cliquant sur le bouton gris à cocher rond à gauche, si votre question est résolue de manière satisfaisante.
Byte Commander

Réponses:

9

Je n'ai pas encore pu tester cela sur un vrai système 17.04 (seulement vérifié qu'il fonctionne sur 16.04), mais vous devriez pouvoir remplacer la commande cdintégrée Bash avec votre propre fonction personnalisée, qui rejette tous les arguments supplémentaires, sauf le premier :

cd(){ command cd "$1" ; }

Mise à jour: Comme suggéré dans le commentaire de @ muru , cette version ci-dessous pourrait mieux fonctionner et prendre en charge les appels cdsans arguments cependant:

cd(){ builtin cd "${@:1:1}"; }

Après avoir entré cette ligne ci-dessus dans votre terminal, vérifiez s'il cdse comporte maintenant comme vous le souhaitez. Si tel est le cas, vous pouvez rendre cette définition de fonction persistante en ajoutant cette ligne à la fin de votre ~/.bashrcfichier. Sinon, il disparaîtra dès que vous aurez terminé votre session shell actuelle.

Notez que si pour une raison quelconque vous devez temporairement utiliser la vraie cdcommande intégrée Bash au lieu de cette fonction personnalisée, vous pouvez simplement l'appeler avec command cdau lieu de plain cd.

Byte Commander
la source
J'écrivais
@Ravexina J'ai également envisagé d'utiliser un alias en premier, mais je l'ai ensuite abandonné car je pense que cela ne peut pas être fait avec un alias, car là vous n'avez pas le contrôle sur les arguments. Par simple curiosité, quelle approche auriez-vous suggérée?
Byte Commander
J'ai fait la même chose, j'ai juste mis le code dans un .shfichier puis créé un alias comme:mcd="source /home/user/bin/cd.sh"
Ravexina
Ah ok. C'est un peu plus compliqué qu'il ne faudrait, mais cela devrait aussi fonctionner.
Byte Commander
2
@SandiHidayat Essayez cd () { builtin cd "${@:1:1}"; }plutôt.
muru
7

Réponse courte / solution de contournement

Pour répondre à votre question dans ce cas précis, cela fonctionne

cd album*1

Mais ce n'est probablement pas la fonctionnalité que vous voulez vraiment.

Qu'est ce qui a changé?

Il semble que config-top.hdans Bash-4.4 a été mis à jour pour ajouter l'option suivante

/* Define CD_COMPLAINS if you want the non-standard, but sometimes-desired
   error messages about multiple directory arguments to `cd'. */

#define CD_COMPLAINS

Et builtins/cd.deffait référence à votre erreur ici:

#if defined (CD_COMPLAINS)
  else if (list->next)
    {
      builtin_error (_("too many arguments"));
      return (EXECUTION_FAILURE);
    }
#endif

Que puis-je faire à long terme?:

Vous pourriez compiler le vôtre bashsans les nouveaux CD_COMPLAINS , mais cela deviendrait fastidieux. Vous pouvez redéfinir les cdfonctionnalités comme suggéré ici ou vous pouvez alias une fonction comme

cd "$(find $1* | head -1)"

Le prouver

Bash 4.4 Beta où cela fonctionne toujours

#Pulling and unpacking source
$ wget https://ftp.gnu.org/gnu/bash/bash-4.4-beta.tar.gz
$ tar -xzvf bash-4.4-beta.tar.gz
$ cd bash-4.4-beta

#Building, go grab something to drink. It's gonna be a while.
~/bash-4.4-beta$ ./configure
~/bash-4.4-beta$ make

#Check Version
~/bash-4.4-beta$ ./bash --version
GNU bash, version 4.4.0(1)-beta (x86_64-unknown-linux-gnu)

#Enter a clean interactive prompt
~/bash-4.4-beta$ env -i PATH="$PWD:$PATH" ./bash --noprofile --norc

#Test example
bash-4.4$ mkdir album-0{1..2}
bash-4.4$ cd album* && pwd
/home/gkent/bash-4.4-beta/album0-1

Version stable de Bash 4.4 là où cela ne fonctionne pas

#Pulling and unpacking source
$ wget https://ftp.gnu.org/gnu/bash/bash-4.4.tar.gz
$ tar -zxvf bash-4.4.tar.gz
$ cd bash-4.4/

#Building, go grab something to drink. It's gonna be a while.
~/bash-4.4$ ./configure
~/bash-4.4$ make

#Check Version
~/bash-4.4$ ./bash -version
GNU bash, version 4.4.0(1)-release (x86_64-unknown-linux-gnu)

#Enter a clean interactive prompt
~/bash-4.4$ env -i PATH="$PWD:$PATH" ./bash --noprofile --norc

#Test example
bash-4.4$ mkdir album-0{1..2}
bash-4.4$ cd album*
bash: cd: too many arguments
Grayson Kent
la source
Désolé, c'était une faute de frappe. Réponse mise à jour.
Grayson Kent
Ah, c'est vrai. Vous pourriez juste faire cd alb*1, pour faire correspondre le littéral 1à la fin même sans les crochets. J'ai confondu votre idée avec autre chose au début.
ilkkachu
5

Je n'ai jamais rencontré ce problème car j'utilise toujours la complétion de tabulation.

Donc, dans votre cas, plutôt que d'avoir une supposition imprécise sur le répertoire que je veux, je taperais cd alTablequel s'il n'y a qu'une seule correspondance, le complète et s'il y en a 2 ou plus complète jusqu'à la fin de la correspondance et TabTabrépertorie les choix.

Voici un exemple de mon système:

cd Un Tab

cd Unknown

suivi par TabTabproduit

Unknown/                        Unknown Artist - Unknown Album/ 
Elder Geek
la source
2

Cela ressemble à un bogue dans Bash: man builtinsl'ancien comportement est le bon.

   cd [-L|[-P [-e]] [-@]] [dir]
              Change the current directory to dir.  if dir is not supplied,
              the  value  of  the  HOME shell variable is the default.  Any
              additional arguments following dir are ignored.

Vous pouvez signaler le bogue sur la bug-bashliste de diffusion; plus de détails ici .


En fait, le bug a été signalé (il y a longtemps). Si vous voulez un Bash fixe maintenant, maintenant, maintenant , voici comment le faire correctement (testé le 17.10, devrait également fonctionner sur d'autres).

Créez d'abord un répertoire dans lequel travailler, par exemple:

mkdir ~/bash
cd ~/bash

Obtenez le package source et les dépendances de génération:

apt-get source bash
sudo apt-get build-dep bash
cd bash-4.4

Modifier config-top.hpour changer cela (devrait être la ligne 32)

#define CD_COMPLAINS

pour ça

/* #define CD_COMPLAINS */

Modifiez debian/changeloget ajoutez une entrée comme celle-ci en haut (vous pouvez également utiliser la commande dch -i):

bash (4.4-5ubuntu1+cd) artful; urgency=medium

  * Fix cd.

 -- Firas Kraiem <firas@fkraiem.org>  Thu, 04 Jan 2018 21:11:22 +0900

Les points les plus importants sont d'ajouter +fooau numéro de version actuel ( foopeut être n'importe quelle chaîne de lettres minuscules; et soyez prudent si vous utilisez dch -i, il incrémentera le dernier numéro, vous devez donc le revenir à la version actuelle) et utiliser le nom correct de la version ( artfulici). Enfin, exécutez dpkg-source --commit.

Vous pouvez ensuite exécuter la debuildcommande, et si tout se passe bien (les erreurs debsignpeuvent être ignorées), vous devriez avoir des .debs dans le répertoire parent, que vous pouvez installer comme d'habitude (il n'est pas nécessaire de les installer tous, juste ceux que vous maintenant; utilisez dpkg -l | grep bashpour le savoir).

Notez que le numéro de version du nouveau package est défini de sorte que vous obtiendrez automatiquement toute future mise à jour vers bash; si la mise à jour ne résout pas le problème, vous devez répéter le processus ci-dessus.

(Cette réponse a d'abord été publiée sur cette question en double .)

fkraiem
la source