Tôi có thể nối vào lệnh cd không?


9

Tôi đang cố gắng thiết lập một cái gì đó trên máy chủ mà tôi chạy, khi tôi cdvào public_htmlthư mục 95% thời gian sẽ có một vài lệnh tôi sẽ luôn chạy để kiểm tra một số thứ.

Có dù sao tôi có thể nối vào cdđể nếu thư mục là một public_html, nó sẽ tự động chạy các lệnh cho tôi?

Nếu tôi không thể tham gia vào cdlệnh, liệu tôi có thể làm gì khác để đạt được kết quả mà tôi đang theo đuổi không?

Tôi đang chạy CentOS 5.8.

Câu trả lời:


12

Bạn có thể thêm chức năng này vào .bashrctập tin khởi động của bạn hoặc khác (tùy thuộc vào trình bao của bạn).

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

Ồ, điều này có vẻ thú vị. Tôi đã thêm cái này vào .bash_profile của tôi và thêm một đầu ra echo "Testing..."ngay phía trên if, nhưng thông báo đầu ra. Tôi có cần làm gì để áp dụng những thay đổi này không?
TMH

@TomHart Nếu bạn không bắt đầu một phiên mới thì bạn phải lấy tệp vào phiên hiện tại của mình trước. ~/.bash_profile
UVV

@TomHart có vẻ như không có /bin/cdtrong CentOS của tôi, vì vậy giải pháp này có thể sẽ không hoạt động
UVV

Bây giờ tôi mới nhận ra điều đó. Tôi tìm thấy câu hỏi này trong đó nêu rõ lý do tại sao unix.stackexchange.com/questions/116955/where-is-cd-located . Vẫn là một giải pháp tốt cho hệ thống thực sự có / bin / cd :).
TMH

1
Không hoạt động nếu bạn cd -P public_htmlhoặc cd ~/public_htmlcó hành vi bất ngờ nếu bạn không thể cdtham gia public_html.
Stéphane Chazelas

17

Với kshhoặc bash(hoặc zsh):

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

Với zsh:

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

( chpwdLà một móc hàm được gọi bất cứ khi nào thư mục làm việc hiện tại thay đổi (bằng cách cd, pushd, popd...)).


3

Gói cd, một lệnh hiện có, không được khuyến khích.

Một giải pháp phổ quát hơn sẽ là xác định một chpwdmóc tùy chỉnh trong Bash. (Theo các thẻ của câu hỏi này, tôi giả sử bạn đang sử dụng Bash)

Không có một hệ thống móc hoàn chỉnh nào được thiết kế ở Bash khi so sánh với các loại đạn pháo hiện đại khác. PROMPT_COMMANDbiến được sử dụng như một hàm hook, tương đương với precmdhook trong ZSH, fish_prompttrong Fish. Hiện tại, ZSH là lớp vỏ duy nhất tôi biết có tích hợp chpwdmóc.

PROMPT_COMMAND

Nếu được đặt, giá trị được hiểu là một lệnh để thực thi trước khi in từng dấu nhắc chính ($ PS1).

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

chpwd Móc ở Bash

Một mẹo được cung cấp để thiết lập một chpwdhook tương đương trong Bash dựa trên 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}"

Kể từ khi chúng tôi phát hiện PWDsự thay đổi trực tiếp, giải pháp làm việc với cd, pushdpopd.

Lưu ý : Sự khác biệt chính giữa chpwdtriển khai của chúng tôi trong Bash và chpwdtrong ZSH là, PROMPT_COMMANDkhông được hỗ trợ trong trình bao Bash không tương tác.

Sử dụng

_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"

Nguồn: Tạo chpwd Hook Equivalent Hook trong Bash từ ý chính của tôi.

Đối với bất cứ ai muốn một câu trả lời cho ZSH. Sử dụng chpwdmóc trong ZSH. Đừng xác định chpwd()chức năng trực tiếp. Chi tiết hơn ở đây .


1

Tôi không phải là chuyên gia bash nhưng tôi sẽ lấy câu trả lời của @ UVV và sửa đổi nó chỉ một chút để nó thực hiện điều này:

  • thay vì kiểm tra public_html, tôi chỉ kiểm tra một số hook-scripttệp trong thư mục đích $1, giả sử , cd_hook.sh.
  • nếu điều đó hook-scripttồn tại, hãy chạy nó và tiếp tục vớicd

Điều này có vẻ chung chung hơn vì sau đó bạn có thể áp dụng cd-hook cho bất kỳ thư mục nào nếu bạn chọn, chỉ bằng cách thêm một cd_hook.shtrong thư mục đã nói.


3
Có vẻ chung chung, nhưng bạn đang giới thiệu một lỗ hổng bảo mật. Chẳng hạn, ai đó hoặc thứ gì đó chỉ cần tạo một tập lệnh hook trong / tmp để khiến bạn chạy bất kỳ mã nào vào lần tới khi bạn cd ở đó. Ít nhất bạn muốn đảm bảo rằng tập lệnh hook thuộc sở hữu của bạn, không phải là một liên kết tượng trưng, ​​không thể ghi được bởi bất kỳ ai khác ngoài bạn, rằng thư mục trong đó chỉ có thể ghi được bởi bạn ... Xem Lưu giữ lịch sử trên mỗi thư mục làm việc (xem mỗi phiên vỏ) cho một cách tiếp cận an toàn hơn.
Stéphane Chazelas

Cảm ơn vì cái nhìn sâu sắc về bảo mật @ StéphaneChazelas. Tôi phải thừa nhận tôi thậm chí không nghĩ về nó.
mất và tìm thấy

Tôi đã tìm thấy câu hỏi này trong khi thực hiện điều đó: nếu tôi cdở đâu đó, hãy kiểm tra một .bashcdtệp và chạy nó nếu nó tồn tại.
DarkWiiPlayer 23/12/18

0

Sử dụng phương pháp zsh mạnh mẽ trong bash:

Đầu tiên một cách dễ dàng để mở rộng bash:

~ / .slscripts

#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
}

Bao gồm trong .bashrc:

. ~/.run_scripts

run_scripts ~/.bashrc.d

Bạn có thể tạo ~ / .bashrc.d / cdhook với:

#!/bin/bash

chpwd() {
  : #no action
}

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

Bây giờ là tùy thuộc vào bạn để thay thế chức năng:

#list files after cd
chpwd() {
  ls -lah --color
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.