Skrypt do zmiany bieżącego katalogu (cd, pwd)


Odpowiedzi:


63

Jest to oczekiwane zachowanie, które zostało już kilkakrotnie omówione.

Skrypt jest uruchamiany w podpowłoce i nie może zmienić katalogu roboczego powłoki nadrzędnej. Jego efekty są tracone po zakończeniu.

Aby trwale zmienić katalog, powinieneś pobrać skrypt, jak w

. ./script

8
@ Sony: Zauważ, że powinieneś użyć, returnaby uciec od skryptu pochodzącego w ten sposób, a nie exit- są one jak funkcje powłoki i exitopuszczą powłokę, z której pochodzi skrypt.
Charles Stewart,

@CharlesStewart W rzeczywistości nie jestem zaznajomiony ze skryptami źródłowymi. Dziękuję Ci!
Sony Santos,

5
jest source ./scripttaki sam?
amyassin,

2
@amyassin: tak, to jest
enzotib,

2
1. .i sourcesą równi w bash. 2. nie musimy używać ./przed nazwą pliku, jeśli znajduje się w tym samym katalogu. Można uruchomić tylko to:. script
sobi3ch

19

W przypadku małych zadań, takich jak to, zamiast tworzyć skrypt, utwórz taki alias,

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

Powinieneś dodać to do swojego .bashrcpliku, jeśli chcesz ustawić dla każdej interaktywnej powłoki.

Teraz możesz uruchomić to jako $ cdproj.


1
Możesz także wywołać echo poleceń do wykonania, a następnie użyć eval `./script` lub eval $(./script)wykonać te polecenia. Jest to powszechne podejście do poleceń, które muszą zaktualizować środowisko powłoki wywołującej.
Keith Thompson,

2
Bądź bardzo ostrożny w kwestii tego, co wypiszesz, jeśli zamierzasz zastosować evalpodejście.
jw013,

13

Użyj exec bashna końcu

Skrypt bash działa w bieżącym środowisku lub w środowisku potomnym, ale nigdy w środowisku macierzystym.

Jednak to pytanie jest często zadawane, ponieważ chce się pozostać w wierszu polecenia bash w określonym katalogu po wykonaniu skryptu bash z innego katalogu.

W takim przypadku po prostu uruchom podrzędną instancję bash na końcu skryptu:

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

To tworzy nową podpowłokę. Wpisz, exitaby powrócić do pierwszej powłoki, w której skrypt został początkowo uruchomiony.


Lepiej po prostu źródło skryptu, jak w zaakceptowanej odpowiedzi: używanie execjest zwykle uważane za ostateczność łajdaka .. :)
neuronet

1
ta sztuczka nie działa w debian 9 stretch.
vdegenne

3
To niewłaściwy sposób na to!
Dennis Williamson

4
Ponieważ nikt nie szczegółowo opisał problemów z tym (patrzę na ciebie, @Dennis): (1) Za każdym razem, gdy to uruchomisz, tworzy nowy, trwały proces bash. Zrób to dziesięć lub dwadzieścia razy w sesji, a będziesz mieć na sobie od 11 do 21 procesów bashowych. Może to wpłynąć na wydajność, a jeśli spróbujesz zakończyć sesję czysto, wpisując exit(lub Ctrl + D), musisz to zrobić 11 do 21 razy. (2) Kolejną wadą używania skryptu wykonywalnego jest to, że jeśli ustawisz jakieś opcje powłoki (np.  dotglobLub  globstar) w interaktywnej sesji powłoki, stracisz je, ponieważ zaczynasz nową powłokę.
G-Man mówi „Przywróć Monikę”

1
Bardzo fajne rozwiązanie! Przepisałem swój alias w bash_profile, więc teraz jest to skrypt przechowywany w osobnym pliku. Używam skryptu, aby przejść do nowo utworzonego folderu tymczasowego. A teraz jeszcze łatwiej jest mieć tymczasową sesję bash. SRP w akcji! Dzięki!
artyom.razinov

8

Chociaż istnieją odpowiedzi, które wykonują dokładnie taką akcję, jaką chcesz, bardziej standardową metodą do tego celu jest utworzenie dowiązania symbolicznego:

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

Następnie możesz cdprzejść do katalogu, używając nazwy proj:

cd proj

Ta metoda jest bardziej elastyczna, ponieważ można uzyskać dostęp do plików przy użyciu krótkiej nazwy bez cd:

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


4

W zależności od tego, co zamierzasz zrobić, innym rozwiązaniem może być utworzenie funkcji zamiast skryptu.

Przykład:

Utwórz funkcję w pliku, powiedzmy /home/aidin/my-cd-script:

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

Następnie dołącz go do swojego bashrclub zshrcpliku:

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

Teraz możesz używać go jak polecenia:

$ my-cd

0

Dlaczego nie użyć „exec”, to robi dokładnie to, co chcę.

#!/bin/bash

cd someplace
exec bash

~/someplace

1
Uważaj na rzeczy, które wydają się być tym, czego chcesz. (Gigantyczny drewniany koń! Właśnie tego chciałem!) Za każdym razem, gdy go uruchomisz, tworzy nowy, trwały proces bash. Zrób to dziesięć lub dwadzieścia razy w sesji, a będziesz mieć ułożonych od 11 do 21 procesów bash. Może to wpłynąć na wydajność, a jeśli spróbujesz zakończyć sesję czysto, wpisując exit(lub Ctrl + D), musisz to zrobić 11 do 21 razy.
G-Man mówi „Przywróć Monikę”

Zdecydowanie mogłem zobaczyć, gdzie to będzie problem. Dla mnie jednak używam go raz, wykonuję pracę, której potrzebuję, a następnie wychodzę. Jeśli to jedyna wada, z którą mogę sobie poradzić. Z drugiej strony, jeśli istnieje lepsze rozwiązanie, chętnie przyjrzę się temu.
Paul

Odpowiedź Aidina na to pytanie za pomocą funkcji powłoki oraz odpowiedź Sachina Divekara przy użyciu aliasu są (IMO) lepszymi rozwiązaniami niż użycie skryptu. PS Kolejną wadą korzystania ze skryptu jest to, że jeśli ustawisz jakieś opcje powłoki (np.  dotglobLub  globstar), stracisz je, ponieważ zaczynasz nową powłokę. … (Ciąg dalszy)
G-Man mówi „Przywróć Monikę”

( Ciąg dalszy )… PPS Właśnie zauważyłem, że w zasadzie powtarzasz odpowiedź Serge'a Stroobandta i pytasz : „Dlaczego tego nie zrobisz?” Na  Stack Exchange oczekujemy odpowiedzi na nowe pomysły i / lub informacje, a nie tylko dyskusji inne odpowiedzi.
G-Man mówi „Przywróć Monikę”

-1

Możesz to zrobić za pomocą funkcji lub za pomocą && Przykłady poniżej instalują Zabbix i tworzą plik z linią w nim zawartą.

Dawny:

#!/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

lub:

#!/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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.