2009-06-12 20 views
8

Có tương đương với bash pushd/popd build trong lệnh cho KSH không?pushd/popd trên ksh?

Đối với những người không biết những gì pushd và popd trong bash làm, đây là mô tả từ trang người đàn ông

pushd [-n] [dir] 
    pushd [-n] [+n] [-n] 
      Adds a directory to the top of the directory stack, or rotates 
      the stack, making the new top of the stack the current working 
      directory. With no arguments, exchanges the top two directo- 
      ries and returns 0, unless the directory stack is empty. 


    popd [-n] [+n] [-n] 
      Removes entries from the directory stack. With no arguments, 
      removes the top directory from the stack, and performs a cd to 
      the new top directory. Arguments, if supplied, have the fol- 
      lowing meanings: 

Cảm ơn

+0

Cài đặt 'pushd' /' popd' xuất sắc xuất hiện [ở đây] (http://blogs.oracle.com/nico/entry/ksh_functions_gal quặng) trong một trong những blog của Oracle - có lẽ liên quan đến việc sử dụng nó trong Solaris. – Mei

Trả lời

10

Khi tôi phát hiện ra rằng ksh không bao gồm những điều này, tôi đã viết của riêng mình. Tôi đặt này trong ~/bin/dirstack.ksh và tập tin .kshrc tôi bao gồm nó như thế này:

. ~/bin/dirstack.ksh 

Dưới đây là nội dung của dirstack.ksh:

# Implement a csh-like directory stack in ksh 
# 
# environment variable dir_stack contains all directory entries except 
# the current directory 

unset dir_stack 
export dir_stack 


# Three forms of the pushd command: 
# pushd  - swap the top two stack entries 
# pushd +3  - swap top stack entry and entry 3 from top 
# pushd newdir - cd to newdir, creating new stack entry 

function pushd 
{ 
    sd=${#dir_stack[*]} # get total stack depth 
    if [ $1 ] ; then 
     if [ ${1#\+[0-9]*} ] ; then 
     # ======= "pushd dir" ======= 

     # is "dir" reachable? 
     if [ `(cd $1) 2>/dev/null; echo $?` -ne 0 ] ; then 
      cd $1    # get the actual shell error message 
      return 1   # return complaint status 
     fi 

     # yes, we can reach the new directory; continue 

     ((sd = sd + 1))  # stack gets one deeper 
     dir_stack[sd]=$PWD 
     cd $1 
     # check for duplicate stack entries 
     # current "top of stack" = ids; compare ids+dsdel to $PWD 
     # either "ids" or "dsdel" must increment with each loop 
     # 
     ((ids = 1))   # loop from bottom of stack up 
     ((dsdel = 0))  # no deleted entries yet 
     while [ ids+dsdel -le sd ] ; do 
      if [ "${dir_stack[ids+dsdel]}" = "$PWD" ] ; then 
       ((dsdel = dsdel + 1)) # logically remove duplicate 
      else 
       if [ dsdel -gt 0 ] ; then  # copy down 
        dir_stack[ids]="${dir_stack[ids+dsdel]}" 
       fi 
       ((ids = ids + 1)) 
      fi 
     done 

     # delete any junk left at stack top (after deleting dups) 

     while [ ids -le sd ] ; do 
      unset dir_stack[ids] 
      ((ids = ids + 1)) 
     done 
     unset ids 
     unset dsdel 
     else 
     # ======= "pushd +n" ======= 
     ((sd = sd + 1 - ${1#\+})) # Go 'n - 1' down from the stack top 
     if [ sd -lt 1 ] ; then ((sd = 1)) ; fi 
     cd ${dir_stack[sd]}   # Swap stack top with +n position 
     dir_stack[sd]=$OLDPWD 
     fi 
    else 
     # ======= "pushd" ======= 
     cd ${dir_stack[sd]}  # Swap stack top with +1 position 
     dir_stack[sd]=$OLDPWD 
    fi 
} 

function popd 
{ 
    sd=${#dir_stack[*]} 
    if [ $sd -gt 0 ] ; then 
     cd ${dir_stack[sd]} 
     unset dir_stack[sd] 
    else 
     cd ~ 
    fi 
} 

function dirs 
{ 
    echo "0: $PWD" 
    sd=${#dir_stack[*]} 
    ((ind = 1)) 
    while [ $sd -gt 0 ] 
    do 
     echo "$ind: ${dir_stack[sd]}" 
     ((sd = sd - 1)) 
     ((ind = ind + 1)) 
    done 
} 
+0

Điều này có vẻ như là câu trả lời hứa hẹn nhất, tôi sẽ thử sau bữa trưa – hhafez

+0

Tôi hy vọng nó hoạt động cho bạn. Tôi đã sử dụng nó trong hơn một thập kỷ. Nó không * chính xác * tái tạo hành vi của pushd/popd/dirs được tích hợp vào csh/bash, nhưng nó rất gần. – Eddie

+0

Rất đẹp. Tôi đã tìm thấy điều này ngày hôm nay và sẽ thiết lập nó như là tiêu chuẩn trên các hệ thống ksh mà tôi làm việc với. :) –

2

Tôi thường sử dụng một subshell cho các loại điều này:

(cd tmp; echo "test" >tmpfile) 

này thay đổi vào thư mục tmp và tạo ra một tập tin gọi là tmpfile trong thư mục đó. Sau khi trở về subshell, thư mục hiện tại được khôi phục về những gì nó đã được trước khi subshell bắt đầu. Điều này là do mỗi cá thể shell có ý tưởng riêng của nó về "thư mục hiện tại" là gì, và việc thay đổi thư mục hiện tại trong một vỏ con không ảnh hưởng đến vỏ được gọi là nó.

0

Nếu hệ thống của bạn không nhận ra lệnh pushd, hãy kiểm tra hồ sơ của bạn.ksh tệp để đảm bảo rằng có một cuộc gọi đến dir.ksh.

+0

dir.ksh là gì? – hhafez

+0

pushd là một hàm hệ vỏ được định nghĩa trong tệp $ ROOTDIR/etc/dir.ksh. –

+0

Không có trên bất kỳ máy chủ Solaris nào mà tôi có. Đầu tiên, tôi không có $ ROOTDIR được định nghĩa và thứ hai,/etc không có bất kỳ tệp .ksh nào trong đó. – Eddie

3

Nếu bạn là OK chỉ với một mức duy nhất trở lại theo dõi bạn có thể bí danh 'cd -' hoặc 'cd $ OLDPWD' thành popd.

Đối với dir.ksh ... theo Google nó là một phần của một commercial package:

LƯU Ý

popd là một chức năng được xác định KornShell trong file

$ROOTDIR/etc/dir.ksh. 

này tệp thường được xử lý bởi một vỏ đăng nhập trong khi xử lý tệp $ ROOTDIR/etc/profile.ksh. Nếu , hệ thống của bạn không thể nhận ra lệnh pop2 , hãy kiểm tra hồ sơ của bạn.ksh tệp để đảm bảo rằng cuộc gọi đến dir.ksh được bao gồm.

SẴN

MKS Toolkit dành cho người dùng điện MKS Toolkit cho hệ thống quản trị MKS Toolkit for Developers MKS Toolkit cho Khả năng cộng tác MKS Toolkit cho Professional Developers MKS Toolkit cho phát triển Doanh nghiệp MKS Toolkit cho phát triển Doanh nghiệp 64 Bit Ấn bản

+0

Tôi sử dụng cd - nhưng đôi khi tôi cần nhiều hơn :) – hhafez

+1

Tên 'dir.sh' là đủ chung chung để nó có thể ở khắp mọi nơi. Hơn nữa, tôi không nghĩ rằng bộ công cụ MKS là xung quanh nữa. – Mei

Các vấn đề liên quan