it-swarm-id.com

Bagaimana cara menambahkan path ke PATH dengan benar?

Saya bertanya-tanya di mana jalur baru harus ditambahkan ke variabel lingkungan PATH. Saya tahu ini bisa dicapai dengan mengedit .bashrc (misalnya), tetapi tidak jelas bagaimana melakukan ini.

Cara ini:

export PATH=~/opt/bin:$PATH

atau ini?

export PATH=$PATH:~/opt/bin
994
Paolo

Hal-hal sederhana

PATH=$PATH:~/opt/bin

atau

PATH=~/opt/bin:$PATH

tergantung pada apakah Anda ingin menambahkan ~/opt/bin di akhir (akan dicari setelah semua direktori lain, jika ada program dengan nama yang sama di beberapa direktori) atau di awal (harus dicari sebelum semua direktori lain).

Anda dapat menambahkan beberapa entri sekaligus. PATH=$PATH:~/opt/bin:~/opt/node/bin atau variasi pada pekerjaan pemesanan baik-baik saja. Jangan letakkan export di awal baris karena memiliki komplikasi tambahan (lihat di bawah “Catatan tentang cangkang selain bash”).

Jika PATH Anda dibuat oleh banyak komponen berbeda, Anda mungkin berakhir dengan entri rangkap. Lihat Bagaimana cara menambahkan jalur direktori home untuk ditemukan oleh Unix perintah mana? dan Hapus entri $ PATH duplikat dengan perintah awk untuk menghindari menambahkan duplikat atau menghapusnya.

Beberapa distribusi secara otomatis menempatkan ~/bin di PATH Anda jika ada, omong-omong.

Di mana harus meletakkannya

Masukkan baris untuk memodifikasi PATH di ~/.profile, atau dalam ~/.bash_profile jika itu yang Anda miliki.

Perhatikan bahwa ~/.bash_rc tidak dibaca oleh program apa pun, dan ~/.bashrc adalah file konfigurasi instance interaktif bash. Anda tidak boleh mendefinisikan variabel lingkungan di ~/.bashrc. Tempat yang tepat untuk mendefinisikan variabel lingkungan seperti PATH adalah ~/.profile (atau ~/.bash_profile jika Anda tidak peduli dengan kerang selain bash). Lihat Apa perbedaan antara mereka dan yang mana yang harus saya gunakan?

Jangan letakkan di /etc/environment atau ~/.pam_environment: ini bukan file Shell, Anda tidak dapat menggunakan substitusi seperti $PATH di sana. Dalam file-file ini, Anda hanya bisa menimpa variabel, bukan menambahkannya.

Potensi komplikasi dalam beberapa skrip sistem

Anda tidak perlu export jika variabel sudah ada di lingkungan: setiap perubahan nilai variabel tercermin di lingkungan.¹ PATH hampir selalu ada di lingkungan; semua sistem unix mengaturnya sangat awal (biasanya pada proses pertama, sebenarnya).

Pada saat login, Anda dapat mengandalkan PATH yang sudah ada di lingkungan, dan sudah mengandung beberapa direktori sistem. Jika Anda menulis skrip yang dapat dieksekusi lebih awal saat menyiapkan semacam lingkungan virtual, Anda mungkin perlu memastikan bahwa PATH tidak kosong dan diekspor: jika PATH masih belum disetel , lalu sesuatu seperti PATH=$PATH:/some/directory akan mengatur PATH ke :/some/directory, dan komponen kosong di awal berarti direktori saat ini (seperti .:/some/directory).

if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi

Catatan tentang kerang selain bash

Dalam bash, ksh dan zsh, export adalah sintaks khusus, dan keduanya PATH=~/opt/bin:$PATH dan export PATH=~/opt/bin:$PATH lakukan hal yang benar. Dalam cangkang Bourne/POSIX-style lainnya seperti tanda hubung (yaitu /bin/sh pada banyak sistem), export diuraikan sebagai perintah biasa, yang menyiratkan dua perbedaan:

Jadi di kerang seperti dasbor, export PATH=~/opt/bin:$PATH set PATH ke string literal ~/opt/bin/: diikuti oleh nilai PATH hingga spasi pertama. PATH=~/opt/bin:$PATH (tugas kosong) (tidak memerlukan tanda kutip dan melakukan hal yang benar. Jika Anda ingin menggunakan export dalam skrip portabel, Anda perlu menulis export PATH="$HOME/opt/bin:$PATH", atau PATH=~/opt/bin:$PATH; export PATH (atau PATH=$HOME/opt/bin:$PATH; export PATH untuk portabilitas bahkan ke Bourne Shell yang tidak menerima export var=value dan tidak melakukan ekspansi tilde).

¹ Ini tidak benar pada cangkang Bourne (seperti pada cangkang Bourne yang sebenarnya, bukan cangkang bergaya POSIX modern), tetapi Anda sangat tidak mungkin menemukan cangkang-cangkang tua seperti itu akhir-akhir ini.

Either way bekerja, tetapi mereka tidak melakukan hal yang sama: elemen PATHare diperiksa dari kiri ke kanan. Dalam contoh pertama Anda, executable di ~/opt/bin Akan lebih diutamakan daripada yang diinstal, misalnya, dalam /usr/bin, Yang mungkin atau mungkin tidak seperti yang Anda inginkan.

Secara khusus, dari sudut pandang keamanan, berbahaya untuk menambahkan jalur ke depan, karena jika seseorang dapat memperoleh akses tulis ke ~/opt/bin Anda, mereka dapat menempatkan, misalnya, ls berbeda di sana, yang Anda mungkin akan menggunakan sebagai ganti /bin/ls tanpa memperhatikan. Sekarang bayangkan hal yang sama untuk ssh atau browser atau pilihan Anda ... (Hal yang sama berlaku tiga kali lipat untuk menempatkan. Di jalur Anda.)

88
Ulrich Schwarz

Saya bingung dengan pertanyaan 2 (karena dihapus dari pertanyaan karena masalah yang tidak terkait):

Apa cara yang bisa dilakukan untuk menambahkan lebih banyak jalur pada jalur yang berbeda? Awalnya saya pikir ini bisa melakukan trik:

export PATH=$PATH:~/opt/bin
export PATH=$PATH:~/opt/node/bin

tetapi tidak karena tugas kedua tidak hanya menambahkan ~/opt/node/bin, tetapi juga keseluruhan PATH sebelumnya ditugaskan.

Ini adalah solusi yang mungkin:

export PATH=$PATH:~/opt/bin:~/opt/node/bin

tetapi untuk keterbacaan saya lebih suka memiliki satu tugas untuk satu jalur.

Jika Anda mengatakan

PATH=~/opt/bin

itu semua yang akan ada di PATH Anda. PATH hanyalah variabel lingkungan, dan jika Anda ingin menambahkan ke PATH, Anda harus membangun kembali variabel dengan konten yang Anda inginkan. Yaitu, apa yang Anda berikan sebagai contoh untuk pertanyaan 2 adalah persis apa yang ingin Anda lakukan, kecuali saya benar-benar kehilangan inti pertanyaan.

Saya menggunakan kedua formulir dalam kode saya. Saya memiliki profil umum yang saya instal pada setiap mesin yang saya kerjakan yang terlihat seperti ini, untuk mengakomodasi direktori yang berpotensi hilang:

export PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11
# add optional items to the path
for bindir in $HOME/local/bin $HOME/bin; do
    if [ -d $bindir ]; then
        PATH=$PATH:${bindir}
    fi
done
39
Carl Cravens

Linux menentukan jalur pencarian yang dapat dieksekusi dengan $PATH variabel lingkungan. Untuk menambahkan direktori/data/myscripts ke awal $PATH variabel lingkungan, gunakan yang berikut:

PATH=/data/myscripts:$PATH

Untuk menambahkan direktori itu ke ujung jalan, gunakan perintah berikut:

PATH=$PATH:/data/myscripts

Tetapi sebelumnya tidak cukup karena ketika Anda menetapkan variabel lingkungan di dalam skrip, perubahan itu hanya efektif dalam skrip. Hanya ada dua cara untuk mengatasi batasan ini:

  • Jika dalam skrip, Anda mengekspor variabel lingkungan, itu efektif dalam setiap program yang dipanggil oleh skrip. Perhatikan bahwa itu tidak efektif dalam program yang disebut skrip.
  • Jika program yang memanggil skrip melakukannya dengan memasukkan alih-alih memanggil, perubahan lingkungan apa pun dalam skrip akan efektif dalam program panggilan. Inklusi seperti itu dapat dilakukan dengan perintah titik atau perintah sumber.

Contoh:

$HOME/myscript.sh
source $HOME/myscript.sh

Inklusi pada dasarnya menggabungkan skrip "dipanggil" dalam skrip "panggil". Ini seperti #include dalam C. Jadi itu efektif di dalam skrip atau program "calling". Tetapi tentu saja, itu tidak efektif dalam program atau skrip apa pun yang dipanggil oleh program panggilan. Untuk membuatnya efektif sepanjang rantai panggilan, Anda harus mengikuti pengaturan variabel lingkungan dengan perintah ekspor.

Sebagai contoh, program bash Shell menggabungkan konten file .bash_profile dengan penyertaan. Tempatkan 2 baris berikut di .bash_profile:

PATH=$PATH:/data/myscripts
export PATH

secara efektif menempatkan 2 baris kode tersebut dalam program bash. Jadi dalam bash, variabel $ PATH termasuk $HOME/myscript.sh, dan karena pernyataan ekspor, program apa pun yang dipanggil oleh bash telah diubah $PATH variabel. Dan karena setiap program yang Anda jalankan dari bash Prompt disebut oleh bash, jalur baru ini berlaku untuk apa pun yang Anda jalankan dari bash Prompt.

Intinya adalah bahwa untuk menambahkan direktori baru ke path, Anda harus menambahkan atau menambahkan direktori ke variabel lingkungan $ PATH dalam skrip yang termasuk dalam Shell, dan Anda harus mengekspor $PATH variabel lingkungan.

Informasi lebih lanjut di sini

25
Steve Brown

Untuk beberapa waktu sekarang saya telah menyimpan dua fungsi pathadd dan pathrm yang membantu menambahkan elemen ke path tanpa perlu khawatir tentang duplikasi.

pathadd mengambil argumen jalur tunggal dan argumen after opsional yang jika disediakan akan ditambahkan ke PATH jika tidak, ia akan menambahkannya.

Dalam hampir setiap situasi jika Anda menambahkan ke jalur maka Anda cenderung ingin menimpa apa pun yang sudah ada di jalur, itulah sebabnya saya memilih untuk menambahkan sebelumnya secara default.

pathadd() {
    newelement=${1%/}
    if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then
        if [ "$2" = "after" ] ; then
            PATH="$PATH:$newelement"
        else
            PATH="$newelement:$PATH"
        fi
    fi
}

pathrm() {
    PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|\$\);\1\2;g" -e 's;^:\|:$;;g' -e 's;::;:;g')"
}

Letakkan ini di skrip yang ingin Anda ubah lingkungan PATH dan sekarang bisa Anda lakukan.

pathadd "/foo/bar"
pathadd "/baz/bat" after
export PATH

Anda dijamin tidak akan menambah jalur jika sudah ada di sana. Jika sekarang Anda ingin memastikan /baz/bat pada awalnya.

pathrm "/baz/bat"
pathadd "/baz/bat"
export PATH

Sekarang setiap jalur dapat dipindahkan ke depan jika sudah ada di jalur tanpa menggandakan.

20
Brett Ryan

Saya tidak dapat berbicara untuk distribusi lain, tetapi Ubuntu memiliki file,/etc/environment, yang merupakan jalur pencarian default untuk semua pengguna. Karena komputer saya hanya digunakan oleh saya, saya meletakkan direktori yang saya inginkan di jalur saya di sana, kecuali itu adalah tambahan sementara yang saya masukkan ke dalam skrip.

10
Jim Bradley

Ada beberapa situasi di mana ia menggunakan PATH=/a/b:$PATH mungkin dianggap sebagai cara "salah" untuk menambahkan path ke PATH:

  1. Menambahkan jalur yang sebenarnya bukan direktori.
  2. Menambahkan jalur yang sudah ada di PATH dalam bentuk yang sama.
  3. Menambahkan jalur relatif (karena direktori aktual yang dicari akan berubah ketika Anda mengubah direktori kerja saat ini).
  4. Menambahkan jalur yang sudah ada di PATH dalam bentuk yang berbeda (mis., Alias ​​karena menggunakan symlinks atau ..).
  5. Jika Anda menghindari melakukan 4, tidak memindahkan path ke bagian depan PATH ketika itu dimaksudkan untuk menimpa entri lain di PATH.

Fungsi (khusus Bash) ini melakukan "hal yang benar" dalam situasi di atas (dengan pengecualian, lihat di bawah), mengembalikan kode kesalahan, dan mencetak pesan yang bagus untuk manusia. Kode dan pesan kesalahan dapat dinonaktifkan ketika tidak diinginkan.

prepath() {
    local usage="\
Usage: prepath [-f] [-n] [-q] DIR
  -f Force dir to front of path even if already in path
  -n Nonexistent dirs do not return error status
  -q Quiet mode"

    local tofront=false errcode=1 qecho=echo
    while true; do case "$1" in
        -f)     tofront=true;       shift;;
        -n)     errcode=0;          shift;;
        -q)     qecho=':';          shift;;
        *)      break;;
    esac; done
    # Bad params always produce message and error code
    [[ -z $1 ]] && { echo 1>&2 "$usage"; return 1; }

    [[ -d $1 ]] || { $qecho 1>&2 "$1 is not a directory."; return $errcode; }
    dir="$(command cd "$1"; pwd -P)"
    if [[ :$PATH: =~ :$dir: ]]; then
        $tofront || { $qecho 1>&2 "$dir already in path."; return 0; }
        PATH="${PATH#$dir:}"        # remove if at start
        PATH="${PATH%:$dir}"        # remove if at end
        PATH="${PATH//:$dir:/:}"    # remove if in middle
    fi
    PATH="$dir:$PATH"
}

Pengecualiannya adalah bahwa fungsi ini tidak mengkanonik lintasan yang ditambahkan ke PATH melalui cara lain, jadi jika alias non-kanonik untuk lintasan ada di PATH, ini akan menambah duplikat. Mencoba untuk mengkanoniskan jalur yang sudah ada dalam PATH adalah proposisi yang tidak pasti karena jalur relatif memiliki makna yang jelas ketika diteruskan ke prepath tetapi ketika sudah berada di jalur Anda tidak tahu apa direktori kerja saat ini. kapan ditambahkan.

7
cjs

Untuk menambahkan path baru ke variabel lingkungan PATH:

export PATH=$PATH:/new-path/

Agar perubahan ini diterapkan ke setiap Shell yang Anda buka, tambahkan ke file yang Shell akan sumber ketika dipanggil. Dalam cangkang yang berbeda ini dapat:

  • Bash Shell: ~/.bash_profile, ~/.bashrc atau profil
  • Korn Shell: ~/.kshrc atau .profile
  • Z Shell: ~/.zshrc atau .zprofile

misalnya.

# export PATH=$PATH:/root/learning/bin/
# source ~/.bashrc
# echo $PATH

Anda dapat melihat jalur yang disediakan di output di atas.

7
Amit24x7

Bagi saya (di Mac OS X 10.9.5), menambahkan nama jalur (mis. /mypathname) ke file /etc/paths bekerja dengan sangat baik.

Sebelum mengedit, echo $PATH mengembalikan:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

Setelah diedit /etc/paths dan memulai kembali Shell, variabel $ PATH ditambahkan dengan /pathname. Memang, echo $PATH mengembalikan:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname

Apa yang terjadi itu /mypathname telah ditambahkan ke $PATH variabel.

6
faelx

Inilah solusi saya:

PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[$0]++' | sed "s/\(.*\).\{1\}/\1/")

Satu liner yang bagus dan mudah yang tidak meninggalkan jejak :

5
AJ.