Zmień bieżący katalog ze skryptu Bash


190

Czy można zmienić bieżący katalog ze skryptu?

Chcę stworzyć narzędzie do nawigacji w katalogu w Bash. Utworzyłem skrypt testowy, który wygląda następująco:

#!/bin/bash
cd /home/artemb

Kiedy wykonuję skrypt z powłoki Bash, bieżący katalog się nie zmienia. Czy w ogóle można zmienić bieżący katalog powłoki ze skryptu?


2
Tylko sugestia ulepszenia: jeśli użyjesz pushd(prawdopodobnie przekierowano, aby >/dev/nullukryć jego dane wyjściowe) zamiast cd, możesz później powrócić do poprzedniego katalogu za pomocą popd.
mklement0

Odpowiedzi:


173

Musisz przekonwertować skrypt na funkcję powłoki:

#!/bin/bash
#
# this script should not be run directly,
# instead you need to source it from your .bashrc,
# by adding this line:
#   . ~/bin/myprog.sh
#

function myprog() {
  A=$1
  B=$2
  echo "aaa ${A} bbb ${B} ccc"
  cd /proc
}

Powodem jest to, że każdy proces ma swój bieżący katalog, a po uruchomieniu programu z powłoki jest on uruchamiany w nowym procesie. Standardowe „cd”, „pushd” i „popd” są wbudowane w interpreter powłoki, aby miały wpływ na proces powłoki.

Ustawiając program jako funkcję powłoki, dodajesz własne polecenie w trakcie procesu, a następnie każda zmiana katalogu jest odzwierciedlana w procesie powłoki.


2
jak byś to zrobił w tcsh?
joedborg

4
+1. Jedną z rzeczy, które zauważyłem, było w pliku, musimy zdefiniować funkcję przed jej wywołaniem. Może pomóc komuś tak niedoświadczonemu jak ja.
Bhushan

Jaka jest duża różnica między zdefiniowaniem funkcji a utworzeniem aliasu?
HelloGoodbye,

1
Po utworzeniu tego pliku myprog.sh i dodaniu go do pliku .bashrc, jak uruchomić skrypt? Czy powinienem wywoływać moją funkcję z innego pliku powłoki czy bezpośrednio z powłoki? Wygląda na to, że nie działa w żaden sposób ...
Andrea Silvestri

1
@AndreaSilvestri Albo wyloguj się i zaloguj ponownie, albo źródłowy plik .bashrc. Dodanie go do .bashrc nic nie robi, dopóki .bashrc nie zostanie uruchomiony.
Jon Strayer

214

Po uruchomieniu skryptu tworzony jest nowy proces, który dziedziczy tylko środowisko. Kiedy się kończy, kończy się. Twoje obecne środowisko pozostaje takie, jakie jest.

Zamiast tego możesz uruchomić skrypt w następujący sposób:

. myscript.sh

.Oceni skrypt w obecnej sytuacji, więc to może być zmieniona


4
+1, ponieważ masz rację. Chociaż szczerze wątpię, że za każdym razem będzie potrzebował źródła skryptu zmieniającego katalog. Ponadto .shrozszerzenia są całkowicie eww. Nie używaj ich.
lhunath

1
Tak, zwykle lepiej nie używać tego w ten sposób. Przez większość czasu cieszysz się, że twoje obecne środowisko nie cierpi. Ale potem mam skrypty do wykonania niektórych zadań konfiguracyjnych, w tym zmiany we właściwym miejscu, a potem ja. oni też. Btw. .sh jest oczywiście kwestią stylu osobistego. Prawdopodobnie nie użyłbym tego podczas instalowania skryptów w całym systemie. Ale w moim ~ / bin używam ich, aby wiedzieć, co jest :)
Norbert Hartl

11
@lhunath Dlaczego rozszerzenia .sh są całkowicie eww?
Carl Pritchett,


1
Dla mnie rozumowanie w tym artykule jest fałszywe. Wydaje się, że wynik był znany z góry, ale znalezienie przyczyn tego nie było takie łatwe. Więc uważam, że to kwestia osobistego stylu, nic więcej.
Norbert Hartl

55

W świetle nieczytelności i nadmiernej komplikacji odpowiedzi uważam, że to właśnie powinien zrobić wnioskodawca

  1. dodaj ten skrypt do PATH
  2. uruchom skrypt jako . scriptname

.(Kropka) będzie upewnić się, że skrypt nie jest prowadzony w powłoce dziecięcej.


38

Łącząc powyższe, możesz utworzyć alias

alias your_cmd=". your_cmd"

jeśli nie chcesz pisać wiodącego „.” za każdym razem, gdy chcesz otrzymać skrypt w środowisku powłoki lub po prostu nie chcesz pamiętać, że należy to zrobić, aby skrypt działał poprawnie.


Czy to pozostanie trwałe po ponownym uruchomieniu?
SDsolar

1
@SDsolar Musisz dodać to do pliku ~ / .bashrc, aby było trwałe. Dla mnie działa jak urok.
Rafał G.

Można umieścić w ~ / .bash_aliases
Champ

@Champ ~/.bash_aliasesnie zawsze jest pozyskiwany podczas uruchamiania Bash.
Mateusz Piotrowski

31

Jeśli używasz bash, możesz wypróbować alias:

w pliku .bashrc dodaj ten wiersz:

alias p='cd /home/serdar/my_new_folder/path/'

kiedy wpiszesz „p” w wierszu poleceń, zmieni katalog.


1
+1 dla aliasu. funkcja powłoki jest interesująca, ale OP poprosił o prostą nawigację z cd. Domyślam się, że większość ludzi potrzebuje takiego skryptu do poruszania się po gałęziach kodu źródłowego i do tego alias jest wystarczający
Brad Dre

19

Jeśli uruchomisz skrypt bash, będzie on działał w bieżącym środowisku lub w środowisku swoich dzieci, nigdy na rodzicu.

Jeśli celem jest uruchomienie polecenia: goto.sh / home / test Następnie pracuj interaktywnie w / home / test jednym ze sposobów jest uruchomienie interaktywnej podpowłoki w skrypcie:

#!/bin/bash
cd $1
exec bash

W ten sposób będziesz w / home / test, dopóki nie wyjdziesz (wyjście lub Ctrl + C) tej powłoki.


Myślałem, że to rozwiąże problem z uruchomionym skryptem powłoki, ale zamiast tego uruchamia powłokę i zapomina, co chciałem.
vwvan

13

Dzięki pushd bieżący katalog jest wypychany na stos katalogów i jest zmieniany na podany katalog, popd umieszcza katalog na wierzchu stosu i przechodzi do niego.

pushd ../new/dir > /dev/null
# do something in ../new/dir
popd > /dev/null

2
To odpowiada na moje pytanie - aktywnie wdrażam to rozwiązanie za pomocą skryptu inicjującego S3 i działa ono doskonale. Dzięki @seb.
19h

5

Po prostu idź do

yourusername/.bashrc (or yourusername/.bash_profile on MAC) by an editor

i dodaj ten kod obok ostatniego wiersza:

alias yourcommand="cd /the_path_you_wish"

Następnie zamknij edytor.

Następnie wpisz:

source ~/.bashrc or source ~/.bash_profile on MAC.

teraz możesz użyć: twoje polecenie w terminalu



3

Zasadniczo używamy cd..do powrotu z każdego katalogu. Pomyślałem, aby to ułatwić, podając liczbę katalogów, z którymi musisz wracać naraz. Możesz to zaimplementować za pomocą osobnego pliku skryptu za pomocą polecenia alias. Na przykład:

code.sh

#!/bin/sh
 _backfunc(){
 if [ "$1" -eq 1 ]; then
  cd ..
 elif [ "$1" -eq 2 ]; then
  cd ../..
 elif [ "$1" -eq 3 ]; then
  cd ../../..
 elif [ "$1" -eq 4 ]; then
  cd ../../../..
 elif ["$1" -eq 10]; then
  cd /home/arun/Documents/work
 fi
 }
alias back='_backfunc'   

Po użyciu source code.shw bieżącej powłoce możesz użyć:

$back 2 

wrócić dwa kroki od bieżącego katalogu. Szczegółowo wyjaśnione tutaj . Wyjaśniono tam również, jak umieścić kod w ~ / .bashrc, aby każda nowa otwarta powłoka automatycznie otrzymywała nowe polecenie aliasu. Możesz dodać nowe polecenie, aby przejść do określonych katalogów, modyfikując kod, dodając więcej if conditionsi różne argumenty. Możesz także pobrać kod z git tutaj .


Fajne rozwiązanie, więc nigdy nie
zepsujesz

0

To podejście jest dla mnie łatwiejsze.

Załóżmy, że na osobistym komputerze iMac, w którym jesteś administratorem, w domyślnym katalogu, gdy otwarte jest okno poleceń, / Users / jdoe, będzie to katalog, do którego można przejść: /Users/jdoe/Desktop/Mongo/db.3.2.1 /kosz.

Oto kroki, które można wykonać:

  1. vi mongobin, w którym wpisałem: cd /Users/jdoe/Desktop/Mongo/db.3.2.1/binjako pierwszy wiersz.
  2. chmod 755 mongobin
  3. source mongobin
  4. pwd

Voila!


0

Stworzyłem również narzędzie o nazwie koza , którego można używać w celu ułatwienia nawigacji.

Możesz zobaczyć kod źródłowy na GitHub .

Począwszy od v2.3.1 z przeglądu użycie wygląda następująco:

# Create a link (h4xdir) to a directory:
goat h4xdir ~/Documents/dev

# Follow a link to change a directory:
cd h4xdir

# Follow a link (and don't stop there!):
cd h4xdir/awesome-project

# Go up the filesystem tree with '...' (same as `cd ../../`):
cd ...

# List all your links:
goat list

# Delete a link (or more):
goat delete h4xdir lojban

# Delete all the links which point to directories with the given prefix:
goat deleteprefix $HOME/Documents

# Delete all saved links:
goat nuke

# Delete broken links:
goat fix

0

Lubię robić to samo dla różnych projektów bez uruchamiania nowej powłoki.

W Twoim przypadku:

cd /home/artemb

Zapisz skrypt jako:

echo cd /home/artemb

Następnie uruchom go za pomocą:

\`./the_script\`

Następnie przechodzisz do katalogu przy użyciu tej samej powłoki.



0

Zadeklaruj swoją ścieżkę:

PATH='/home/artemb'     
cd ${PATH}

0

Po prostu napisz PWDi wyeksportuj go do skryptu, a zmiana będzie się utrzymywać.

export PWD=/your/desired/directory
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.