Bisakah saya menghubungkan ke perintah cd?


9

Saya mencoba mengatur sesuatu di server yang saya jalankan, kapan pun saya cdmasuk ke public_htmlfolder 95% dari waktu ada beberapa perintah saya akan selalu berjalan untuk memeriksa hal-hal tertentu.

Apakah masih ada yang bisa saya kaitkan cdjadi jika direktori tersebut adalah public_html, ia akan secara otomatis menjalankan perintah untuk saya?

Jika saya tidak bisa mengaitkan ke cdperintah, apakah ada hal lain yang bisa saya lakukan untuk mencapai hasil yang saya kejar?

Saya menjalankan CentOS 5.8.

Jawaban:


12

Anda dapat menambahkan fungsi ini ke .bashrcfile startup Anda atau lainnya (tergantung pada shell Anda).

cd() {      
   if [ "$1" = "public_html" ]; then
      echo "current dir is my dir"
   fi
   builtin cd "$1"
}

Ooh, ini terlihat menarik. Saya telah menambahkan ini ke .bash_profile saya, dan menambahkan echo "Testing..."output tepat di atas if, tetapi tidak ada. Apakah saya perlu melakukan sesuatu untuk menerapkan perubahan ini?
TMH

@ TomHart Jika Anda tidak memulai sesi baru maka Anda harus sumber file ke sesi Anda saat ini oleh. ~/.bash_profile
UVV

@ TomHart sepertinya tidak ada /bin/cddalam CentOS saya, jadi solusi ini mungkin tidak akan berfungsi
UVV

Saya baru saja memperhatikan itu sekarang. Saya menemukan pertanyaan ini yang menyatakan mengapa unix.stackexchange.com/questions/116955/where-is-cd-located . Masih solusi yang bagus untuk sistem yang benar-benar memiliki / bin / cd :).
TMH

1
Tidak bekerja jika Anda cd -P public_htmlatau cd ~/public_htmlatau memiliki perilaku tak terduga jika Anda tidak bisa cdmenjadi public_html.
Stéphane Chazelas

17

Dengan kshatau bash(atau zsh):

cd() {
  builtin cd "$@" || return
  [ "$OLDPWD" = "$PWD" ] || case $PWD in
      (*/public_html) echo do something
    esac
}

Dengan zsh:

chpwd()
  case $PWD in
    (*/public_html) echo do something
  esac

( chpwdAdalah kait fungsi yang disebut setiap kali direktori kerja saat ini berubah (dengan cara cd, pushd, popd...)).


3

Wrapping cd, perintah yang ada, tidak direkomendasikan.

Solusi yang lebih universal adalah mendefinisikan chpwdpengait kustom di Bash. (Menurut tag pertanyaan ini, saya menganggap Anda menggunakan Bash)

Tidak ada sistem kait lengkap yang dirancang di Bash jika dibandingkan dengan kerang modern lainnya. PROMPT_COMMANDvariabel digunakan sebagai fungsi kait, yang setara dengan precmdkait di ZSH, fish_promptdi Fish. Untuk saat ini, ZSH adalah satu-satunya cangkang yang saya kenal yang memiliki chpwdkait bawaan.

PROMPT_COMMAND

Jika diset, nilai ditafsirkan sebagai perintah untuk dijalankan sebelum pencetakan setiap prompt utama ($ PS1).

https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Bash-Variables

chpwd Hubungkan Bash

Trik disediakan untuk menyiapkan chpwdkait setara di Bash berdasarkan PROMPT_COMMAND.

# create a PROPMT_COMMAND equivalent to store chpwd functions
typeset -g CHPWD_COMMAND=""

_chpwd_hook() {
  shopt -s nullglob

  local f

  # run commands in CHPWD_COMMAND variable on dir change
  if [[ "$PREVPWD" != "$PWD" ]]; then
    local IFS=$';'
    for f in $CHPWD_COMMAND; do
      "$f"
    done
    unset IFS
  fi
  # refresh last working dir record
  export PREVPWD="$PWD"
}

# add `;` after _chpwd_hook if PROMPT_COMMAND is not empty
PROMPT_COMMAND="_chpwd_hook${PROMPT_COMMAND:+;$PROMPT_COMMAND}"

Karena kita mendeteksi PWDperubahan secara langsung, solusi bekerja dengan cd, pushd, dan popd.

Catatan : Perbedaan utama antara chpwdimplementasi kami di Bash dan chpwddi ZSH adalah, PROMPT_COMMANDtidak didukung dalam shell Bash non-interaktif.

Pemakaian

_public_html_action() {
  if [[ $PWD == */public_html ]]; then
    # actions
  fi
}

# append the command into CHPWD_COMMAND
CHPWD_COMMAND="${CHPWD_COMMAND:+$CHPWD_COMMAND;}_public_html_action"

Sumber: Buat Hook Setara chpwd di Bash dari intisari saya.

Bagi siapa pun yang menginginkan jawaban untuk ZSH. Gunakan chpwdkait di ZSH. Jangan mendefinisikan chpwd()fungsi secara langsung. Lebih detail di sini .


1

Saya bukan pakar bash, tetapi saya akan mengambil jawaban @ UVV dan memodifikasinya sedikit sehingga ia melakukan ini:

  • alih-alih memeriksa public_html, saya hanya memeriksa beberapa hook-scriptfile di direktori target $1, katakanlah cd_hook.sh,.
  • jika itu hook-scriptada, jalankan, dan lanjutkan dengancd

Ini tampaknya lebih umum karena Anda kemudian dapat menerapkan cd-hook ke direktori mana pun jika Anda memilih, dengan hanya menambahkan cd_hook.shdi direktori tersebut.


3
Tampaknya generik, tetapi Anda memperkenalkan kerentanan keamanan. Seseorang atau sesuatu hanya perlu menanamkan hook-script di / tmp misalnya untuk membuat Anda menjalankan kode apa pun saat berikutnya Anda melakukan cd di sana. Anda setidaknya ingin memastikan bahwa skrip kait dimiliki oleh Anda, bukan symlink, tidak dapat ditulisi oleh siapa pun selain Anda, bahwa direktori itu hanya dapat ditulisi oleh Anda ... Lihat Menyimpan riwayat per direktori kerja (lih per sesi shell) untuk pendekatan yang lebih aman.
Stéphane Chazelas

Terima kasih atas wawasan keamanan @ StéphaneChazelas. Saya harus mengakui bahwa saya bahkan tidak memikirkannya.
hilang-dan-ditemukan

Saya menemukan pertanyaan ini sambil melakukan hal itu: jika saya di cdsuatu tempat, periksa .bashcdfile dan jalankan jika ada.
DarkWiiPlayer

0

Menggunakan pendekatan zsh yang kuat di bash:

Pertama cara mudah untuk memperpanjang bash:

~ / .runscript

#load all scripts inside $1 dir

run_scripts()
{
    for script in $1/*; do

        # skip non-executable snippets
        [ -f "$script" ] && [ -x "$script" ] || continue

        # execute $script in the context of the current shell
        . $script
    done
}

Sertakan ke dalam .bashrc:

. ~/.run_scripts

run_scripts ~/.bashrc.d

Anda dapat membuat ~ / .bashrc.d / cdhook dengan:

#!/bin/bash

chpwd() {
  : #no action
}

cd() {      
   builtin cd $1
   chpwd $1
}

Sekarang terserah Anda untuk mengganti fungsi:

#list files after cd
chpwd() {
  ls -lah --color
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.