Cd için bir sarmalayıcı yazarken neden cd "$ 1" yerine "$ 1" yerine cd kullanmam gerekiyor?


25

Başka bir yerde aşağıdaki gibi bir cd işlevi gördüm:

cd()
{
 builtin cd "$@"
}

$@yerine kullanmak neden tavsiye edilir $1?

Bir test dizini "r st" oluşturdum ve bu fonksiyonu içeren betiği aradım ve her iki şekilde de işe yaradı.

$ . cdtest.sh "r st"

$ . cdtest.sh r stkullandıysam "$@"da kullanamadım ama "$1"


1
cd "$*"Ayrıca 1'den fazla argüman ile düzgün çalışmayacak.
GoFundMonica - codidact.org

Yanıtlar:


57

Çünkü, göre bash(1), cdargümanlar alır

   cd [-L|[-P [-e]] [-@]] [dir]
          Change  the  current  directory to dir.  if dir is not supplied,
          ...

Bu nedenle, dizin aslında $1bunun yerine, -Lbaşka bir bayrak gibi bir seçenek olabileceği gibi olmayabilir .

Bu ne kadar kötü?

$ cd -L /var/tmp
$ pwd
/var/tmp
$ cd() { builtin cd "$1"; }
$ cd -L /var/tmp
$ pwd
/home/jhqdoe
$ 

Kullanmayı beklediğiniz yerde olmazsanız işler ters gidebilir cd "$1".


19

Kullanarak "$@"tüm argümanlar sadece ilk argümanı geçecekleri cdyere $1geçecektir.

Senin örneklerinde

$ . cdtest.sh "r st"

her zaman sadece bir argümandan geçerken çalışır, ancak bir bayrak gibi

$ . cdtest.sh -L "r st"

O zaman sadece dizini tamamen kaybedecek "$@"şekilde "$1"genişleyeceği yerde doğru şekilde çalışacaktır cd -L.

ancak

$ . cdtest.sh r st

Her iki durumda da cd'ye iki parametre ilettiğinizde başarısız olur rve stbu cd'yi yürütmek için geçerli bir yol değildir. Parametreler, r\ sttek bir argüman olarak değerlendirilmek üzere alıntılanması (ilk örneğinizde olduğu gibi) veya kaçılmış ( ) boşluklarla ayrılır .

Ancak cd durumunda bayrakların geçmesi çok nadirdir ve birden fazla dizine geçemezsiniz, bu nedenle gerçek ya "$1"da "$@"cd kullanımının dünyadaki farkını göremezsiniz . Ancak diğer komutlar için bir fark göreceksiniz , bu nedenle "$@"bir sarmalayıcı işlevi veya böyle bir komut dosyası oluşturmak istediğinizde her zaman kullanmanız en iyisidir .


14

Argüman olmadığı zaman da durum var :

$ cd /tmp; cd; pwd
/home/muru
$ cd_func() { builtin cd "$1"; }
$ cd_func /tmp; cd_func; pwd
/tmp

cdHerhangi bir argüman olmadan giriş dizininde değişiklik yapın. Herhangi bir argüman olmadan hiçbir "$@"şeye "$1"genişlemez , ancak boş dizgeye genişler. Bunlar farklı:

$ args() { for i in "$@"; do echo "|$i|"; done; }
$ args
$ args ""
||

Biraz alakasız, ama: nihayet boş bir tartışmanın neden cdiyi bir şey olduğunu anladım . Ana dizine geçmek yerine bir hataya neden olur. Diğer bazı komutlarda, özellikle rsyncboş bir ilk argüman beklenmeyen davranışlara neden olur (transferin kaynaklarındaki mevcut dizini içerir).
Joe,

4

Bir bash betiğine argümanlar boşlukla sınırlandırılmıştır. 1 $ ilk argümandır. Örneklerinde ...

Örnek 1'de, $ 1, "r st" dizesidir ... ikinci örnekte, $ 1 bir karakter dizesidir 'r' ...

$ @ tüm değişkenlerdir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.