Script untuk mengubah direktori saat ini (cd, pwd)

44

Saya ingin menjalankan skrip untuk mengubah direktori kerja saat ini:

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

Tapi, setelah saya jalankan, pwd saat ini tetap tidak berubah! Bagaimana saya bisa melakukan itu?

Sony Santos
sumber

Jawaban:

63

Itu adalah perilaku yang diharapkan, dan sudah dibahas beberapa kali.

Script dijalankan dalam subkulit, dan tidak dapat mengubah direktori kerja shell induk. Efeknya hilang ketika selesai.

Untuk mengubah direktori secara permanen Anda harus sumber skrip, seperti pada

. ./script
enzotib
sumber
8
@Sony: Perhatikan bahwa Anda harus menggunakan returnuntuk melarikan diri dari skrip yang bersumber dengan cara ini, tidak exit- mereka seperti fungsi shell, dan exitakan keluar dari shell yang bersumber skrip.
Charles Stewart
@CharlesStewart Sebenarnya, saya tidak terbiasa dengan skrip bersumber. Terima kasih!
Sony Santos
5
apakah source ./scriptsama?
amyassin
2
@amyassin: ya, itu
enzotib
2
1. .dan sourcesama di bash. 2. kita tidak perlu menggunakan ./sebelum nama file jika itu di direktori yang sama. Tidak masalah menjalankan hanya ini:. script
sobi3ch
19

Untuk tugas kecil seperti ini, alih-alih membuat skrip, buat alias seperti ini,

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

Anda harus menambahkan ini ke .bashrcfile Anda , jika Anda ingin mengaturnya untuk setiap shell interaktif.

Sekarang Anda dapat menjalankan ini sebagai $ cdproj.

Sachin Divekar
sumber
1
Anda juga dapat meminta skrip mengulangi perintah yang akan dieksekusi, dan kemudian menggunakan eval `./script` atau eval $(./script)menjalankan perintah tersebut. Ini adalah pendekatan umum untuk perintah yang perlu memperbarui lingkungan shell yang memohon.
Keith Thompson
2
Berhati-hatilah dengan apa yang Anda hasilkan jika Anda akan melakukan evalpendekatan.
jw013
13

Gunakan exec bashdi akhir

Skrip bash beroperasi pada lingkungan saat ini atau pada anak-anaknya, tetapi tidak pernah pada lingkungan orang tuanya.

Namun, pertanyaan ini sering ditanyakan karena seseorang ingin ditinggalkan di bash prompt di direktori tertentu setelah eksekusi skrip bash dari direktori lain.

Jika ini masalahnya, jalankan saja instance bash anak di akhir skrip:

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

Ini menciptakan subkulit baru. Ketik exituntuk kembali ke shell pertama tempat skrip awalnya dimulai.

Serge Stroobandt
sumber
Lebih baik sumber skrip, seperti dalam jawaban yang diterima: menggunakan execbiasanya dianggap sebagai upaya terakhir dari bajingan .. :)
neuronet
1
Trik ini tidak bekerja di debian 9 stretch.
vdegenne
3
Ini adalah cara yang salah untuk melakukan ini!
Dennis Williamson
4
Karena tidak ada yang merinci masalah dengan ini (Saya melihat Anda, @ Dennis): (1) Setiap kali Anda menjalankan ini, itu menciptakan proses bash baru yang persisten. Lakukan sepuluh atau dua puluh kali dalam satu sesi, dan Anda akan memiliki 11 hingga 21 proses bash yang menumpuk. Ini dapat memengaruhi kinerja, dan, jika Anda mencoba menghentikan sesi dengan bersih dengan mengetik exit(atau Ctrl + D), Anda harus melakukannya 11 hingga 21 kali. (2) Kelemahan lain dari menggunakan skrip yang dapat dieksekusi adalah, jika Anda mengatur opsi shell (misalnya,  dotglobatau  globstar) dalam sesi shell interaktif Anda, Anda akan kehilangan mereka, karena Anda memulai shell baru.
G-Man Mengatakan 'Reinstate Monica'
1
Solusi yang sangat bagus! Saya telah menulis ulang alias saya di bash_profile jadi sekarang ini adalah skrip yang disimpan dalam file terpisah. Saya menggunakan skrip untuk pergi ke folder sementara yang baru dibuat. Dan sekarang bahkan lebih mudah untuk memiliki sesi bash sementara. SRP beraksi! Terima kasih!
artyom.razinov
8

Meskipun ada jawaban yang melakukan tindakan tepat yang Anda inginkan, metode yang lebih standar untuk tujuan tersebut adalah membuat tautan simbolis:

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

Kemudian Anda bisa cdke direktori menggunakan nama proj:

cd proj

Metode ini lebih fleksibel karena Anda dapat mengakses file menggunakan nama pendek tanpa cd:

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

Jika Anda mengubah di antara direktori yang jauh di sistem file. Saya akan merekomendasikan autojump .

stnly
sumber
4

Bergantung pada apa yang akan Anda lakukan, solusi lain dapat membuat fungsi alih-alih skrip.

Contoh:

Buat fungsi dalam file, katakanlah /home/aidin/my-cd-script:

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

Kemudian sertakan dalam bashrcatau zshrcfile Anda:

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

Sekarang Anda dapat menggunakannya seperti perintah:

$ my-cd
Aidin
sumber
0

Mengapa tidak menggunakan "exec" untuk melakukan apa yang saya inginkan.

#!/bin/bash

cd someplace
exec bash

~/someplace
paul
sumber
1
Waspadalah terhadap hal-hal yang tampaknya Anda inginkan. (Seekor kuda kayu raksasa! Hanya yang saya inginkan!) Setiap kali Anda menjalankan ini, itu menciptakan proses bash baru yang persisten. Lakukan sepuluh atau dua puluh kali dalam satu sesi, dan Anda akan memiliki 11 hingga 21 proses bash yang disusun. Ini dapat memengaruhi kinerja, dan, jika Anda mencoba menghentikan sesi dengan bersih dengan mengetik exit(atau Ctrl + D), Anda harus melakukannya 11 hingga 21 kali.
G-Man Mengatakan 'Reinstate Monica'
Saya pasti bisa melihat di mana itu akan menjadi masalah. Bagi saya, meskipun saya menggunakannya sekali waktu, melakukan pekerjaan yang saya butuhkan dan kemudian keluar. Jika itu satu-satunya kelemahan saya bisa hidup dengan itu. Di sisi lain jika ada solusi yang lebih baik, saya bersedia melihatnya.
paul
Jawaban Aidin untuk pertanyaan ini , menggunakan fungsi shell, dan jawaban Sachin Divekar , menggunakan alias, adalah (IMO) solusi yang lebih baik daripada menggunakan skrip. PS Kelemahan lain dari menggunakan script adalah bahwa, jika Anda menetapkan opsi shell (misalnya,  dotglobatau  globstar), Anda akan kehilangan mereka, karena Anda memulai shell baru. … (Lanjutan)
G-Man Mengatakan 'Reinstate Monica'
(Lanjutkan) ... PPS Saya baru saja memperhatikan bahwa Anda, pada dasarnya, mengulangi jawaban Serge Stroobandt dan mengatakan '' Mengapa tidak melakukan ini? '' Di  Stack Exchange kami mengharapkan jawaban untuk memberikan ide dan / atau informasi baru, dan tidak hanya membahas jawaban lain
G-Man Mengatakan 'Reinstate Monica'
-1

Anda dapat melakukannya menggunakan fungsi atau menggunakan && Contoh di bawah menginstal Zabbix dan membuat file dengan garis di dalamnya.

Ex:

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

atau:

#!/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
Raul Chiarella
sumber