Neden “cd” bir kabuk betiğinde çalışmıyor?


43

Sadece bir senaryo yazmak istiyorum benim dizini değiştirir .

Aşağıdaki komutları dosyaya koydum /home/alex/pathABC

#!/bin/sh
cd /home/alex/Documents/A/B/C
echo HelloWorld

Ben yaptım chmod +x pathABC.

Terminalde iken /home/alexiçerideyim koşuyorum ./pathABCama çıktı tam HelloWorldve güncel dizin değişmedi.

Peki sorun ne?


Yanıtlar:


74

Diğerlerinin de belirttiği gibi, dizin betiğin çağrıldığı terminal işleminde değil, betiğinizin alt işleminde değiştirilir. Çocuk süreci öldükten sonra, olduğu yerde bırakılan terminale geri dönersiniz.

Birkaç alternatif:

1. Sembolik bağlantı

Evinize, kolayca erişmek istediğiniz uzun yola bir bağlantı yerleştirin.

$ ln -s /home/alex/Documents/A/B/C ~/pathABC

sonra dizine şununla eriş:

$ cd ~/pathABC

2. Takma ad

~ / .Bashrc dosyasına bir takma ad ekleyin:

alias pathABC="cd /home/alex/Documents/A/B/C"

( buradan )

3. İşlev

Dizini değiştiren bir işlev yaratın, işlev terminalinizin işleminde çalışır ve dizini değiştirebilir.

( buradan )

4. Çocukken koşmaktan kaçının

Komut dosyanızı çalıştırmak yerine kaynaklayın. Kaynak ( .veya tarafından yapılan source), komut dosyasının kendi alt kabuğu içinde çalışmak yerine aynı kabukta yürütülmesine neden olur.

$ . ./pathABC

( buradan ve buradan )

5. cd-mümkün değişken

İçindeki cdable_varsseçeneği ayarlayın ve ~/.bashrcdizine bir ortam değişkeni oluşturun:

shopt -s cdable_vars
export pathABC="/home/alex/Documents/A/B/C"

Sonra kullanabilirsiniz cd pathABC

( buradan )


15
Şimdi kullanımını anlıyorum source! Neden yaptığımı source .bashrcve yapmadığımı hep merak etmişimdirbash .bashrc
hytromo

Seçenek 3 harika çalıştı. Sadece betiğimin başında go_to_wherever () {cd my / directory} fonksiyonunu tanımladım. İşlemleri bu dizinde çalıştırmadan önce çağırdı.
i2097i

> 5. cd-able vars - değil mi cd $pathABC?
loxaxs

7

Komut dosyasını bir terminalde çalıştırdığınızda, bir alt işlem çalıştırılır. Bu alt programda, yani betiğiniz belirtilen dizine göre değişir. Fakat ana süreçte, yani senaryoyu çalıştırdığınız yer hala eski yoldadır. VEYA sadece şunu söyleyebiliriz:

The scope of cd command is only for child process not parent


2
Buna ek olarak, aradığınız efekti elde etmek için @alex, kaynak kodunu kaynak koduyla ana süreç içinde yürütün : ya . pathABCda source pathABC.
zwets

4

Düşünme hatası yapıyorsun. Geçerli kabuk aynı dizinde kalırken, komut dosyası yeni dizine taşındı.

Dizini değiştirdikten sonra yeni dizinde başka bir komut dosyası oluşturarak ve komut dizinizden çalıştırarak görebilirsiniz:

#!/bin/sh
cd /home/alex/Documents/A/B/C && ./another_script.sh # (if it is executable)

İkinci komut dosyası yeni dizinden çalışır.

HelloWorld 

sadece betiğin çıktısıdır.


3
HelloWorld ana kabuğa "geri dönmedi", standart çıktıya çıktı
Mog

pwdDuruma tamamen yeni bir komut dosyası eklemek yerine sadece yeni dizinde çalışırsanız daha net olabilir .
wjandrea

0

Merhaba dünya sadece bir izleme ifadesi olduğu için, şunu deneyelim:

Aşağıdaki cd.shiçeren bash betiği dosyası oluşturun:

#!/bin/bash
echo "/home/mike/Documents/A/B/C"
  • .shUzatma bash komut vererek eski bir kongre bir uzantı filenames olduğunu. Tamamen kozmetik ve genellikle gereksiz. Ancak bu durumda çekirdek cdkomuttan ayrılmak önemlidir .

Aşağıdakileri kullanarak çalıştırılabilir bash betiği dosyasını işaretleyin:

chmod a+x cd.sh

Şimdi dosyayı çalıştırın:

$ cd $(./cd.sh)
bash: cd: /home/alex/Documents/A/B/C: No such file or directory
  • cd hepimiz biliyoruz.
  • $(...) Parantez içindeki komutu çalıştırır ve çıktı döndürür.
  • Yolunuzdaysa cd.sh, nerede olduğunu belirtmeniz gerekmez. ./Komutun geçerli dizinde olduğunu belirtmek için ile önek eklenir .
  • echoÇıktısı cd.shkomut dosyası yoluyla ebeveyne geri gönderilir $(...). Ana (bizim kabuk istemimiz) bu çıktıyı kullanır ve Linux cdkomutuna iletir.

Diğerlerinin de söylediği gibi, bir çocuk işlemi ebeveynin dizinini değiştiremez. Bu, çocuğun ebeveyne süreç sona erdikten sonra nereye gideceğini söyleyebilmesinin bir yoludur.


@wjandrea Bir telefonda kodlama için aldığınız şey bu! Eve yeni geldim, düzelteceğim. Teşekkürler. Sadece kontrol ettim ve iyi çalışıyor. Belki 14.04bir saat kadar önce okuduğum sürümündür.
WinEunuuchs2Unix

Senaryoyu tamamen değiştirdin. Önceden sadece bir komut vardı: cd /home/mike/Documents/A/B/Cbu herhangi bir çıktı üretmedi. Şimdi echo "/home/mike/Documents/A/B/C"çıktı üretiyor.
wjandrea

@wjandrea Doğru, ayrıca betiği çağıran yolu da tamamen değiştirdim. Basit yerine ./cd.shşimdi cd $(./cd.sh)değil, ancak ebeveynin mevcut dizinini değiştiren çocuğun amacını gerçekleştirir. Evet sıradışı ama insanların ilginç bulmasını umarım bunu yapmanın başka bir yolu.
WinEunuuchs2Unix
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.