Ubuntu 17.04 — bash:cd:参数过多


10

我刚刚将Ubuntu 16.04升级到17.04,发现cd命令有点问题。

假设我有两个文件夹:album-01album-02

在Ubuntu 16.04中,如果执行cd album*此操作,它将转到找到的第一个文件夹album-01

但是在新的Ubuntu 17.04中,如果执行cd album*此操作会导致我 -bash: cd: too many arguments

cdcd在Ubuntu 16.04中一样,如何在Ubuntu 17.04中进行制作?


4
当您给出cd两个位置时,您所得到的确是有道理的,并且希望以某种方式找出您想要的位置。
mikewhatever

1
@mikewhatever不幸的是,Bash手册与您不同意:“ 目录之后的任何其他参数都将被忽略”
muru

3
如果有人感兴趣,请发布错误报告:bugs.launchpad.net/ubuntu/+source/bash/+bug/1683576
muru

如果您的问题得到了令人满意的解决,请不要忘记单击左侧的灰色圆形复选按钮,以接受对您最有帮助的答案。
字节指挥官

Answers:


9

我还不能在实际的17.04系统上进行测试(仅验证它可以在16.04上运行),但是您应该能够cd使用自己的自定义函数覆盖Bash内置命令,该命令会丢弃除第一个参数以外的所有其他参数:

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

更新:@muru的注释中所建议,以下版本可能会更好,并且支持cd不带参数的调用:

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

在终端中在上方输入此行后,请确认cd现在是否以您想要的方式运行。在这种情况下,可以通过在~/.bashrc文件末尾添加该行来使该函数定义持久化。否则,它将在您结束当前的Shell会话后消失。

请注意,如果出于某种原因暂时需要使用真正的cdBash内置命令代替此自定义函数,则可以使用command cd而不是plain 来简单地调用它cd


我在写相同的东西,而不是在函数中,我在建议小脚本的别名...确保它起作用;)
Ravexina

@Ravexina我也考虑过先使用别名,但随后删除了该名称,因为我认为不能使用别名来完成,因为那里没有对参数的控制权。出于好奇,您会建议哪种方法?
字节指挥官

我做了同样的事情,我只是将代码放入.sh文件中,然后创建了一个别名,例如:mcd="source /home/user/bin/cd.sh"
Ravexina

喔好吧。这比需要的要复杂一些,但是应该也可以。
字节指挥官

2
@SandiHidayat尝试尝试cd () { builtin cd "${@:1:1}"; }
muru

7

简短答案/解决方法

在这种情况下回答您的问题

cd album*1

但这可能不是您真正想要的功能。

发生了什么变化?

看来config-top.h在Bash-4.4中已更新为添加以下选项

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

#define CD_COMPLAINS

builtins/cd.def在这里引用您的错误:

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

我可以长期做什么?

您可以在bash没有新的CD_COMPLAINS的情况下编译自己的文件,但这会很乏味。您可以重新定义cd此处建议的功能,也可以为以下功能添加别名

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

证明它

Bash 4.4 Beta仍然可以使用

#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

Bash 4.4稳定版本无法正常工作

#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,

嗯对 您可以这样做cd alb*11即使没有括号也可以匹配末尾的文字。首先,我将您的想法与其他东西混淆了。
ilkkachu

5

我从来没有遇到过这个问题,因为我总是使用Tab Completion。

因此,在您的情况下,我不会键入cd alTab一个关于我想要哪个目录的准确答案,而是键入一个(如果只有一个匹配项的话)完成该匹配,以及如果有两个或多个完整的匹配项(直到匹配结束并TabTab列出选择项)。

这是我系统中的一个示例:

cd Un Tab

cd Unknown

其次是TabTab农产品

Unknown/                        Unknown Artist - Unknown Album/ 

2

这看起来像是Bash中的错误:按照man builtins旧的行为,这是正确的行为。

   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.

您可以在bug-bash邮件列表中报告该错误。更多细节在这里


实际上,该错误已报告(很久以前)。如果您现在,现在,现在都想要固定的Bash,请按以下步骤正确操作(已在17.10上测试,也应适用于其他Bash )。

首先创建一个工作目录,例如:

mkdir ~/bash
cd ~/bash

获取源包和构建依赖关系:

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

编辑config-top.h以更改此设置(应为第32行)

#define CD_COMPLAINS

对此

/* #define CD_COMPLAINS */

编辑debian/changelog并在顶部添加这样的条目(您也可以使用命令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

最重要的一点是追加+foo当前版本号(foo可以是任何小写字母的字符串;请注意,如果使用dch -i,它将增加最后一个数字,因此您需要将其还原为当前版本)并使用正确的发行名称(artful此处)。最后,运行dpkg-source --commit

然后debuild,您可以运行该命令,如果一切顺利(debsign可以忽略有关的错误),则应.deb在父目录中包含一些s,您可以照常安装(无需安装所有s,只需安装您自己的现在;用于dpkg -l | grep bash查找)。

请注意,已设置新软件包的版本号,以便将来自动更新为bash;。如果更新不能解决问题,则必须重复上述过程。

(此答案首先发布在此重复问题上。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.