Ubuntu 17.04 - bash: cd: มีอาร์กิวเมนต์มากเกินไป


10

ฉันเพิ่งอัพเกรด Ubuntu 16.04 เป็น 17.04 และพบปัญหาเล็กน้อยกับcdคำสั่ง

สมมติว่าฉันมีสองโฟลเดอร์: album-01&album-02

ใน Ubuntu 16.04 ถ้าฉันทำcd album*มันจะไปที่โฟลเดอร์แรกที่พบalbum-01

แต่ใน Ubuntu 17.04 ใหม่ถ้าฉันทำcd album*มันจะส่งผลให้ฉัน -bash: cd: too many arguments

วิธีทำcdใน Ubuntu 17.04 เหมือนcdใน Ubuntu 16.04


4
สิ่งที่คุณได้รับนั้นสมเหตุสมผลในขณะที่คุณcdระบุสถานที่สองแห่งและคาดหวังว่ามันจะเป็นสิ่งที่คุณต้องการ
mikewhething

1
@mikewhething แต่น่าเสียดายที่คู่มือ Bashไม่เห็นด้วยกับคุณ: "ข้อโต้แย้งเพิ่มเติมใด ๆ ต่อไปนี้ไดเรกทอรีจะถูกละเว้น"
muru

3
โพสต์รายงานข้อผิดพลาดในกรณีที่ใครสนใจ: bugs.launchpad.net/ubuntu/+source/bash/+bug/1683576
muru

โปรดอย่าลืมยอมรับคำตอบที่ช่วยคุณได้มากที่สุดด้วยการคลิกปุ่มตรวจสอบรอบสีเทาทางด้านซ้ายหากคำถามของคุณได้รับการแก้ไขอย่างน่าพอใจ
ผู้บัญชาการไบต์

คำตอบ:


9

ฉันยังไม่สามารถทดสอบสิ่งนี้ในระบบ 17.04 จริง ๆ (ตรวจสอบแล้วว่ามันทำงานได้กับ 16.04) แต่คุณควรสามารถแทนที่cdคำสั่งในตัวของ Bash ด้วยฟังก์ชันที่กำหนดเองของคุณเองซึ่งจะทิ้งอาร์กิวเมนต์เพิ่มเติมใด ๆ ยกเว้นตัวแรก :

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

อัปเดต:ตามที่แนะนำในความคิดเห็นของ @ muruเวอร์ชันด้านล่างนี้อาจทำงานได้ดีขึ้นและรองรับการโทรcdโดยไม่มีข้อโต้แย้งว่า:

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

หลังจากที่คุณป้อนบรรทัดนี้ด้านบนในเทอร์มินัลของคุณโปรดตรวจสอบว่าcdตอนนี้มีพฤติกรรมในแบบที่คุณต้องการ หากเป็นกรณีนี้คุณสามารถทำให้คำจำกัดความของฟังก์ชันนี้คงอยู่ได้โดยการต่อท้ายบรรทัดนั้นจนสุด~/.bashrcไฟล์ มิฉะนั้นจะหายไปทันทีที่คุณจบเซสชันเชลล์ปัจจุบัน

โปรดทราบว่าถ้าด้วยเหตุผลใดก็ตามที่คุณต้องการชั่วคราวที่จะใช้จริงcdทุบตีในตัวคำสั่งแทนการฟังก์ชั่นที่กำหนดเองนี้คุณก็สามารถเรียกมันว่าด้วยแทนที่จะธรรมดาcommand cdcd


ฉันกำลังเขียนสิ่งเดียวกันแทนที่จะฟังก์ชั่นฉันแนะนำให้นามแฝงแก่สคริปต์ตัวจิ๋ว ... แน่ใจว่ามันใช้งานได้)
Ravexina

@Ravexina ฉันคิดว่าใช้นามแฝงเป็นอันดับแรกเช่นกัน แต่หลังจากนั้นก็ลดลงเพราะฉันคิดว่ามันไม่สามารถทำได้ด้วยนามแฝงเพราะคุณไม่สามารถควบคุมข้อโต้แย้งได้ แค่อยากรู้อยากเห็นคุณจะแนะนำวิธีการอย่างไร
ผู้บัญชาการ Byte

ฉันทำสิ่งเดียวกันฉันเพิ่งใส่รหัสลงใน.shไฟล์จากนั้นสร้างนามแฝงเช่น:mcd="source /home/user/bin/cd.sh"
Ravexina

อาโอเค. นั่นเป็นเรื่องที่ซับซ้อนเกินกว่าที่ควรจะเป็น แต่ควรจะได้ผลเช่นกัน
ผู้บัญชาการ Byte

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 Stable Release ที่มันไม่ทำงาน

#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*1เพื่อจับคู่ตัวอักษร1ในตอนท้ายโดยไม่ต้องใส่วงเล็บ ฉันสับสนความคิดของคุณกับสิ่งอื่นในตอนแรก
ilkkachu

5

ฉันไม่เคยพบปัญหานี้เพราะฉันใช้การใช้แท็บเสร็จสมบูรณ์เสมอ

ดังนั้นในกรณีของคุณแทนที่จะคาดเดาไม่แน่ชัดว่าฉันต้องการไดเรกทอรีใดฉันจะพิมพ์cd alTabว่าหากมีเพียงหนึ่งรายการที่ตรงกันให้ทำมันให้เสร็จและหากมี 2 รายการหรือมากกว่านั้นเสร็จสิ้นขึ้นไปถึงจุดที่การจับคู่สิ้นสุดและ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 ควรทำงานกับผู้อื่นด้วย)

สร้างไดเรกทอรีเพื่อทำงานก่อนเช่น:

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ในไดเรกทอรีหลักซึ่งคุณสามารถติดตั้งได้ตามปกติ (ไม่จำเป็นต้องติดตั้งพวกเขาทั้งหมดเพียงคนที่คุณ มีตอนนี้ใช้dpkg -l | grep bashเพื่อค้นหา)

โปรดทราบว่าหมายเลขรุ่นของแพคเกจใหม่มีการตั้งค่าเพื่อให้คุณโดยอัตโนมัติจะได้รับการปรับปรุงในอนาคตใด ๆ ที่จะbash; หากการอัปเดตไม่สามารถแก้ไขปัญหาได้คุณจะต้องทำซ้ำขั้นตอนข้างต้น

(คำตอบนี้ถูกโพสต์ครั้งแรกในคำถามที่ซ้ำกันนี้)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.