Geçerli dizini değiştirmek için komut dosyası (cd, pwd)


44

Geçerli çalışma dizinini değiştirmek için bir komut dosyası çalıştırmak istiyorum:

#!/bin/bash
cd web/www/project

Ancak, çalıştırdıktan sonra, mevcut pwd değişmeden kalır! Bunu nasıl yapabilirim?

Yanıtlar:


63

Beklenen bir davranış ve zaten birkaç kez tartışıldı.

Komut alt kabukta çalıştırılır ve üst kabuk çalışma dizinini değiştiremez. Tamamlandığında etkileri kaybolur.

Değişim dizinine kalıcı olmalıdır kaynak olduğu gibi, komut

. ./script

8
@Sony: returnBu şekilde yazılmış bir betikten kaçmak için kullanmanız gerektiğine dikkat edin , exitbunlar kabuk işlevlerine benzemez exitve betiği alan kabuktan çıkacaktır.
Charles Stewart

@CharlesStewart Aslında, ben kaynaklı script ile aşina değilim. Teşekkür ederim!
Sony Santos

5
olan source ./scriptaynı?
amyassin

2
@amyassin: evet, öyle
enzotib

2
1. .ve sourcebash eşittir. 2. ./Aynı dizinde ise dosya adından önce kullanmamız gerekmez . Sadece bu çalıştırmak için sorun yok:. script
sobi3ch

19

Bunun gibi küçük işler için, komut dosyası oluşturmak yerine, bunun gibi bir diğer ad oluşturun,

$ alias cdproj='cd /dir/web/www/proj'

.bashrcHer etkileşimli kabuk için ayarlanmasını istiyorsanız, bunu dosyanıza eklemelisiniz .

Şimdi bunu çalıştırabilirsin $ cdproj.


1
Komut dosyasının yürütülmesi gereken komutları yankılamasını ve sonra bu komutları çalıştırmak için eval `./script` veya tuşunu kullanmasını da sağlayabilirsiniz eval $(./script). Bu, çağrılan kabuğun ortamını güncellemesi gereken komutlar için yaygın bir yaklaşımdır.
Keith Thompson

2
evalYaklaşmaya gidecekseniz ne çıktıya dikkat edin .
jw013

13

exec bashSonunda kullanın

Bir bash betiği şu anki ortamında veya çocuklarının üzerinde çalışır, ancak hiçbir zaman ana ortamında çalışmaz.

Ancak, bu soruya genellikle bir bash betiğinin başka bir dizinden çalıştırılmasından sonra belli bir dizinde bash isteminde bırakılmak istendiği için sorulur .

Bu durumda, betiğin sonunda bir alt bash örneği yürütün:

#!/usr/bin/env bash
cd desired/directory
exec bash

Bu yeni bir alt kabuk yaratır. Tip exitkomut başlangıçta başlatıldı ilk kabuk dönmek için.


Sadece bir kaynaktan kabul edilen cevap olarak komut, Better: kullanarak exectipik bir hainin son çare olarak kabul edilir .. :)
Neuronet

1
bu numara debian 9 ile çalışmıyor.
vdegenne

3
Bu konuda gitmek için yanlış bir yoldur!
Dennis Williamson

3
Kimse bununla ilgili problemleri ayrıntılı bir şekilde açıklamadığı için (Sana bakıyorum, @Dennis): (1) Bunu her çalıştırdığında, yeni, kalıcı bir bash işlemi yaratıyor. Bir seansta on veya yirmi kez yapın; üst üste 11 ila 21 bash işleminiz olacak. Bu performansı etkileyebilir ve oturumu temiz bir şekilde yazarak exit(veya Ctrl + D) sonlandırmayı denerseniz , bunu 11 ila 21 kez yapmanız gerekir. (2) Yürütülebilir bir komut dosyası kullanmanın başka bir dezavantajı, etkileşimli kabuk oturumunuzda herhangi bir kabuk seçeneği (örneğin  dotglobveya  globstar) ayarlarsanız, onları kaybedeceksiniz, çünkü yeni bir kabuk başlatıyorsunuzdur.
G-Man,

1
Çok güzel bir çözüm! Takma adımı bash_profile dosyasına yeniden yazdım, bu yüzden şimdi ayrı bir dosyada depolanan bir betik. Yeni oluşturulan geçici bir klasöre gitmek için komut dosyasını kullanıyorum. Ve şimdi geçici bir bash seansı yapmak daha da kolay. SRP eylemde! Teşekkürler!
artyom.razinov

8

İstediğiniz işlemi yapan cevaplar olsa da, bu amaç için daha standart bir yöntem sembolik bir bağlantı oluşturmaktır:

ln -s ~/web/www/project proj   #use full path to dir!

Sonra cdismini kullanarak dizine gidebilirsiniz proj:

cd proj

Bu yöntem daha esnektir çünkü kısa adı kullanarak dosyalara erişemezsiniz cd:

ls proj/   #note the endslash!
vim proj/file.x

4

Dosya sistemindeki dizinler arasında değişiklik yaparsanız. Ben tavsiye eder autojump .


4

Ne yapacağınıza bağlı olarak, başka bir çözüm bir komut dosyası yerine bir işlev oluşturmak olabilir.

Örnek:

Bir dosyada bir işlev oluşturun diyelim /home/aidin/my-cd-script:

function my-cd() {
  cd /to/my/path
}

Sonra onu bashrcveya zshrcdosyanıza ekleyin :

# Somewhere in rc file
source /home/aidin/my-cd-script

Şimdi bir komut gibi kullanabilirsiniz:

$ my-cd

0

Neden "exec" kullanılmıyorsa tam olarak ne istersem onu ​​yapar.

#!/bin/bash

cd someplace
exec bash

~/someplace

1
İstediğin gibi görünen şeylere dikkat et . (Dev bir tahta at! Tam istediğim!) Bunu her çalıştırdığınızda, yeni, kalıcı bir bash işlemi yaratır. Bir oturumda on veya yirmi kez yapın; yığılmış 11 ila 21 bash işlemine sahip olacaksınız. Bu performansı etkileyebilir ve oturumu temiz bir şekilde yazarak exit(veya Ctrl + D) sonlandırmayı denerseniz , bunu 11 ila 21 kez yapmanız gerekir.
G-Man

Bunun nerede bir problem olacağını kesinlikle görebiliyordum. Benim için bir kez kullanıyorum, ihtiyacım olan işi yapıyorum ve sonra çıkıyorum. Ancak bununla yaşayabileceğim tek dezavantajı varsa. Öte yandan daha iyi bir çözüm varsa bakmaya hazırım.
Paul,

Aidin bu soruya bir kabuk işlevi kullanarak cevabı ve Sachin Divekar'ın bir diğer adı kullanarak cevabı bir komut dosyası kullanmaktan (IMO) daha iyi çözümlerdir. Not: Bir komut dosyası kullanmanın başka bir dezavantajı, herhangi bir kabuk seçeneği (örneğin,  dotglobveya  globstar) ayarlarsanız, onları kaybedeceksiniz, çünkü yeni bir kabuk başlatıyorsunuzdur. … (Devam ediyor)
G-Man 'Monica'yı Yeniden Girin' diyor

(Devamı) ... PPS Sadece yineledi temelde olduğunu fark Serge Stroobandt yanıtını 'At '? Bunu neden' ve' diyerek  Stack Borsası yeni fikirler ve / veya bilgi vermek cevapları bekliyoruz ve sadece tartışmak değil diğer cevaplar
G-Man 'Monica'yı Yeniden Girin' Demişti

-1

Bunu bir işlev kullanarak veya && kullanarak yapabilirsiniz. Aşağıdaki örnekler Zabbix'i yükler ve içinde bir çizgi bulunan bir dosya oluşturur.

Ör:

#!/bin/bash

# Create Function:
installZabbix(){
    cd /usr/src/zabbix-4.2.4;
    ./configure --enable-agent;
    make install;
    cd /usr/src/;
    >file;
    echo "Hi, this is a file." >>file;
}

# Call the function:
installZabbix

veya:

#!/bin/bash
cd /usr/src/zabbix-4.2.4 && ./configure --enable-agent && make install && cd /usr/src && >file && echo "Hi, this is a file." >>file
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.