Neden bir yol adı çıktısını bir komuttan “cd” ye yönlendiremiyorum?


27

cdBaşka bir komuttan yönlendirilen bir dizin adı almaya çalışıyorum . Bu yöntemlerden hiçbiri çalışmıyor:

$ echo $HOME | cd
$ echo $HOME | xargs cd

Bu işe yarıyor:

$ cd $(echo $HOME)

Neden ilk komut dizisi çalışmıyor ve bu şekilde de başarısız olan başkaları var mı?


Başkaları tarafından, bu şekilde başarısız olan cd kullanmak için diğer komutlara veya diğer yöntemlere mi atıfta bulunuyorsunuz?
Didi Kohen

@DavidKohen Diğer komutlara atıfta bulunuyorum
Jhonathan

Dikkate değer bazı örnekler; ulimit, umask, popd, pushd, set, export ve oku.
Didi Kohen

Yanıtlar:


32

cdharici bir komut değil - bir kabuk yerleşik işlevidir. Geçerli kabuk bağlamında çalışır ve harici komutların yaptığı gibi bir çatal / exec'd bağlamında ayrı bir işlem olarak gerçekleştirilmez.

Üçüncü örneğiniz işe yarıyor, çünkü kabuk değişkeni ve cdyerleşik ifadeyi çağırmadan önce komut ikamesini genişletiyor , böylece bağımsız değişkeninin cddeğerini alıyor ${HOME}.

POSIX sistemleri yapmak bir ikili var cd- benim FreeBSD makinede, en bulunuyor /usr/bin/cdama düşündüğün yapmaz. İkilinin çağrılması, cdkabuğun binary'i çatallamasına / yürütmesine neden olur, bu da çalışma dizinini aktardığınız ada değiştirir. Bununla birlikte, en kısa sürede, ikili çıkar ve çatal / yürütme işlemi kaybolur ve sizi başlamadan önce bulunduğu dizinde bulunan kabuğunuza döndürür.


10
Hangisi bir merak uyandırır Dış cdkomutun amacı nedir ?
kojiro

23

cdstandart girişi okumaz. Bu yüzden ilk örneğiniz işe yaramıyor.

xargsBir komut ismine, yani bağımsız bir yürütülebilir dosyanın ismine ihtiyaç duyar. cdBir kabuğun yerleşik komutu olması gerekir ve eğer uygulanabilir bir dosya olsaydı (o dizinde değişiklik yapabileceğinizi ve otomobil dizinleri için olması muhtemel yan etkilerini doğrulamak dışında) bir etkisi olmazdı. Bu yüzden ikinci örneğiniz işe yaramıyor.


4

Mevcut iyi cevabın yanı sıra, bir borunun kendi ayrı çalışma dizinine sahip olan yeni bir süreci belirttiğinden de bahsetmek gerekir. Bu nedenle, bunu yapmaya çalışmak işe yaramaz:

echo test | cd /

Böylece, kabuk bu komuttan döndükten sonra / klasöründe olmayacaksınız.


Bir boru hattındaki tüm komutlar farklı işlemlerde çalışır, bu nedenle, içinde ve yerleşik a | bolsa bile , en az biri kabuk işleminde işlemez, ancak hangisinin hangisi olduğuna dair hiçbir garanti yoktur. AT & T Mesela , ya , da kod götürecek diye / cari kabuk sürecinde orada çalıştırılır. abkshzshbash -O lastpipeb
Stéphane Chazelas

4

Zaten verilen doğru cevaplara ek olarak: bash çalıştırıyorsanız ve cd gibi bir "komut" un ne olduğunu öğrenmek istiyorsanız, türü kullanabilirsiniz.

$ type cd
cd is a shell builtin

ya da neden olmasın:

$ type time
time is a shell keyword

Örneğin, normal zamandaki gnu süresi zaten favori dağıtımınıza dahil edilmişse:

$ which time
/usr/bin/time

Tamam tamam fikrini anladın mı, peki neyin türü?

$ type type
type is a shell builtin

İşte bir bash manuel pasajı:

       type [-aftpP] name [name ...]
          With no options, indicate how each name would be interpreted  if  used  as  a
          command name.  If the -t option is used, type prints a string which is one of
          alias, keyword, function, builtin,  or  file  if  name  is  an  alias,  shell
          reserved word, function, builtin, or disk file, respectively.  If the name is
          not found, then nothing is printed, and an exit status of false is  returned.
          If  the -p option is used, type either returns the name of the disk file that
          would be executed if name were specified as a command  name,  or  nothing  if
          ‘‘type  -t  name’’ would not return file.  The -P option forces a PATH search
          for each name, even if ‘‘type -t name’’ would not return file.  If a  command
          is  hashed,  -p  and -P print the hashed value, not necessarily the file that
          appears first in PATH.  If the -a option is used,  type  prints  all  of  the
          places  that  contain  an  executable  named name.  This includes aliases and
          functions, if and only if the -p option is  not  also  used.   The  table  of
          hashed  commands  is  not  consulted when using -a.  The -f option suppresses
          shell function lookup, as with the command builtin.  type returns true if any
          of the arguments are found, false if none are found.

0

Diğerlerinin de dediği gibi, işe yaramaz çünkü cdharici bir program değil, kabuk yerleşik bir komut olduğundan, herhangi bir şeyi içine aktarabileceğiniz standart bir girişi yoktur.

Ancak, çalışsa bile, istediğini yapmaz: bir boru yeni bir işlem başlatır ve ilk komutun standart çıktısını ikincinin standart girişine yönlendirir, böylece yalnızca yeni süreç mevcut çalışmasını değiştirebilir dizin; bu, ilk süreci hiçbir şekilde etkileyemedi.


2
İkinci paragrafınız doğru. Fakat yine de ilk paragraf: neden kabuk yerleşiklerinin stdin olmadığını varsayıyorsunuz? readgenellikle (her zaman?) kabuk yapılıdır. cdStdin'i görmezden geldiği doğrudur , ancak bunun bir yerleşik olması nedeniyle değildir.
dubiousjim

-2

Başka bir seçenek, bir komutun stdout'unu, ikinci bir komutun komut satırı argümanı olarak yerleştiren ve ondan daha taşınabilir olan backticks'tir $(...). Örneğin:

cd `echo $HOME`

veya daha genel olarak;

cd `anycommand -and whatever args`

Geri tepme çubuklarının kullanımının, komutu çalıştırmak ve çıktıyı komut satırında değiştirmek için kullanılan kabuğa bağlı olduğunu unutmayın. Çoğu kabuk onu destekliyor.


3
OP, daha önce sorduğu gibi $(...)çalıştığını belirtti. Bunun yerine backticks tavsiye etmenin iyi bir tavsiye olduğunu sanmıyorum, çünkü çok daha karmaşık alıntı kuralları var ve genellikle hataya daha açık. (Bkz . Bash Referans El Kitabındaki §3.5.4 "Komuta Değiştirme" .)
ruakh

$ () desteklendiğinde güzeldir, ancak geri tepmeler farklı mermiler ve sistemler arasında daha yaygın olarak desteklenir. Ancak bunu "başka bir seçenek" olarak değiştirmeliyim.
Seth Noble

Farklı mermiler, evet; ama farklı "sistemler"? Gerçekten $(...)bir sistemde destekleyebilecek herhangi bir kabuk var mı ?
ruakh

4
-1, soruyu hiç cevaplamıyor.
Bernhard

3
@ ruakh ve Seth: Tüm POSIX mermileri desteği $(…). POSIX kabuğuna sahip olmayan sistemler (yani orijinal bir Bourne kabuğuna sahip) aşırı derecede eski olacaktır. /bin/shBourne kabuğu olan ve /usr/xpg4/bin/shPOSIX kabuğu almak gibi başka bir yola ihtiyaç duyduğunuz sistemler bile günümüzde nadirdir. Antik unix boxen'i profesyonelce yönetmeyenlere backticks tavsiye etmek, onlara bir kötülük yapmaktır.
Gilles 'SO- kötülük yapmayı bırak'
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.