이 bash 코드에서이 세 가지를 설명해 주시겠습니까?


10

나는이 function내에서 .bashrc파일. 나는 그것이 무엇을하는지, 그것은 X 많은 디렉토리를 강화합니다.cd

여기있어:

up()
{
    local d=""
    limit=$1
    for ((i=1 ; i <= limit ; i++))
      do
        d=$d/..
      done
    d=$(echo $d | sed 's/^\///')
    if [ -z "$d" ]; then
      d=..
    fi
    cd $d
}

하지만이 세 가지를 설명해 주시겠습니까?

  1. d=$d/..
  2. sed 's/^\///'
  3. d=..

왜 이렇게하지 않습니까?

up()
{
    limit=$1

    for ((i=1 ; i <= limit ; i++))
    do
        cd ..
    done
}

용법:

<<<>>>~$ up 3
<<<>>>/$

답변:


24
  1. d=$d/..변수 /..의 현재 내용에 추가 d합니다. d비어있는 상태로 시작한 다음 첫 번째 반복 /..에서 두 번째 /../..등을 만듭니다 .

  2. sed 's/^\///'삭제 제 /그래서 /../..된다  ../..(이것은, 파라미터의 확장을 사용하여 수행 될 수있다 d=${d#/}).

  3. d=.. 조건의 맥락에서만 의미가 있습니다.

    if [ -z "$d" ]; then
      d=..
    fi
    

    이렇게하면 d이 시점에서 비어 있으면 상위 디렉토리로 이동합니다. ( up인수가없는 것은와 같습니다 cd ...)

이 접근 방식은 한 단계에서 이전 디렉토리 (사용자 관점에서)로 돌아갈 수있는 기능을 cd ..유지하기 때문에 반복보다 낫습니다 cd -.

기능을 단순화 할 수 있습니다 :

up() {
  local d=..
  for ((i = 1; i < ${1:-1}; i++)); do d=$d/..; done
  cd $d
}

이것은 우리가 최소한 한 레벨 위로 올라가고 n-1 레벨을 추가한다고 가정 하므로 선행을 제거 /하거나 비어 있는지 확인할 필요가 없습니다 $d.

Athena 사용 jot( athena-jotDebian 의 패키지) :

up() { cd $(jot -b .. -s / "${1:-1}"); }

( glenn jackman이 제안한 변형을 기반으로 함 ).


그러나 $OLDPWD짓밟히는 것이 생각났다. 그리고 zsh cd에서 dirstack을 사용하도록 설정되어 있습니다.
muru

루프에서 사용 $1하는 limit대신에 할당 해야 할 이유가 $1있습니까?
Nick Matteo

1
@kundor는 기본값이 0인지 확인합니다 ( 쉘 산술 참조 ). ${1:-1}glenn의 변형에서와 같이 대신 사용할 수 있습니다 .
Stephen Kitt

@kundor 또한 사람의 가독성. 이름이 잘 알려진 변수는 함수를 읽기 시작할 때 함수가 무엇을하는지 알거나 함수를 추론하기 위해 코드를 이해하지 않아도 첫 번째 인수 의 의도 된 의미 또는 목적 을 알려줍니다 .
mtraceur

2

하지만이 세 가지를 설명해 주시겠습니까?

  1. d = $ d / ..

    이 VAR의 현재 내용을 연결해 d과를 /..다시에 할당합니다 d.
    최종 결과는 d처럼 반복되는 문자열 을 만드는 것 /../../../..입니다.

  2. sed 's / ^ ///'

    게시 한 코드에서 /제공된 문자열 d(echo $ d)에서 행간 을 제거하십시오 . 백 슬래시를 피하기 위해
    작성하는 것이 좋습니다 sed 's|^/||'.

    대안은 더 빠르고 간단 d=${d#/}합니다.

  3. d = ..

    문자열 ..을 var에 할당하십시오 d.
    이것은 테스트 에 var 이 비어 있다는 신호가있는 경우 하나d 이상 을 보장하는 방법으로 만 의미 가 있습니다. 그리고 그것은 sed 명령이에서 하나의 문자를 제거하기 때문에 발생할 수 있습니다 . d에서 문자를 제거 할 필요가 없으면 or 가 필요하지 않습니다 . ..if [ -z "$d" ]; thendd
    sedif


귀하의 질문에있는 코드는 항상 적어도 하나 이상의 디렉토리로 이동합니다.

보다 나은

  • local d변수가 비어 있는지 확인하기에 충분하며 다른 것은 필요하지 않습니다.
    그러나 로컬은 bash 또는 dash와 같은 일부 쉘에서만 작동합니다. 특히 ksh(as yash)에는 local명령 이 없습니다 . 보다 휴대용 솔루션은 다음과 같습니다.

    [ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
  • for((구문 휴대용 아니다. 다음과 같은 것을 더 잘 사용하십시오.

    while [ "$((i+=1))" -lt "$limit" ]; do
  • 건장한.
    함수의 첫 번째 인수에 제공된 값이 음수이거나 텍스트 일 ​​수 있으면 해당 값을 처리하기 위해 함수가 강력해야합니다.
    먼저 값을 숫자로만 제한합니다 (에 사용할 것 c입니다 count).

    c=${1%%[!0-9]*}

    그런 다음 카운트 값을 양수 값으로 만 제한하십시오.

    let "c = (c>0)?c:0"

이 함수는 0 또는 모든 텍스트를 오류없이 받아들입니다.

up()
{
    [ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
    c=${1%%[!0-9]*}
    c=$(((c>0)?c:0))
    while [ "$((i+=1))" -le "$c" ]; do d="$d../"; done
    echo \
        cd "${d%/}"         # Removing the trailing / is not really needed for cd
                            # but it is nice to know it could be done cleanly.
}

up 2
up 0
up asdf

echo \기능을 테스트했을 때를 제거하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.