programing

bash에 "goto"라는 문구가 있나요?

megabox 2023. 4. 9. 21:19
반응형

bash에 "goto"라는 문구가 있나요?

bash에 "goto"라는 문구가 있나요? 나쁜 관행으로 간주되는 것은 알지만, 저는 특별히 "goto"가 필요합니다.

디버깅을 위해 큰 스크립트의 일부를 건너뛰기 위해 사용하는 경우(Karl Nicoll의 코멘트 참조), false가 적절한 옵션인 경우(false가 항상 사용 가능한지는 확실하지 않습니다.저에게는 /bin/false에 있습니다).

# ... Code I want to run here ...

if false; then

# ... Code I want to skip here ...

fi

# ... I want to resume here ...

디버깅 코드를 리핑할 때 문제가 발생합니다.if false 구문은 매우 간단하고 기억에 남습니다만, 어떻게 일치하는 fi를 찾을 수 있을까요?편집기에서 들여쓰기를 차단할 수 있는 경우 건너뛴 블록을 들여쓸 수 있습니다(그러면 작업이 끝나면 다시 넣어야 합니다).아니면 fi line에 댓글을 달 수도 있지만, 기억할 만한 것이어야 합니다. 프로그래머 의존도가 매우 높을 것으로 생각됩니다.

아니요, 없습니다. 존재하는 제어 구조에 대한 정보는 Bash 참조 매뉴얼§ 3.2.4 "복합 명령어"를 참조하십시오.특히, 의 언급에 주의해 주십시오.break ★★★★★★★★★★★★★★★★★」continue하지 않아요.goto이 높아 하는 데 이 될 수

일부 디버깅 또는 데먼스트레이션 요구에 도움이 될 수 있습니다.

Bob Copeland 솔루션 http://bobcopeland.com/blog/2012/10/goto-in-bash/이 우아하다는 것을 알게 되었습니다.

#!/bin/bash
# include this boilerplate
function jumpto
{
    label=$1
    cmd=$(sed -n "/$label:/{:a;n;p;ba};" $0 | grep -v ':$')
    eval "$cmd"
    exit
}

start=${1:-"start"}

jumpto $start

start:
# your script goes here...
x=100
jumpto foo

mid:
x=101
echo "This is not printed!"

foo:
x=${x:-10}
echo x is $x

결과는 다음과 같습니다.

$ ./test.sh
x is 100
$ ./test.sh foo
x is 10
$ ./test.sh mid
This is not printed!
x is 101

하시면 됩니다.case위해 bash: 고토 흉내를 낸다.

#!/bin/bash

case bar in
  foo)
    echo foo
    ;&

  bar)
    echo bar
    ;&

  *)
    echo star
    ;;
esac

생산:

bar
star

bash 스크립트를 테스트/디버깅하고 있을 때 단순히 1개 이상의 코드 섹션을 건너뛰는 경우, 여기에 매우 간단한 방법이 있습니다(위의 대부분의 방법과는 달리).

#!/bin/bash

echo "Run this"

cat >/dev/null <<GOTO_1

echo "Don't run this"

GOTO_1

echo "Also run this"

cat >/dev/null <<GOTO_2

echo "Don't run this either"

GOTO_2

echo "Yet more code I want to run"

, 「Delete」라고 하는 이 있는 는 삭제해당 행에는, 「Delete」라고 하는 입니다.GOTO.

용액을 만들 도 있습니다.goto이치노

#!/bin/bash

shopt -s expand_aliases
alias goto="cat >/dev/null <<"

goto GOTO_1

echo "Don't run this"

GOTO_1

echo "Run this"

goto GOTO_2

echo "Don't run this either"

GOTO_2

echo "All done"

에일리어스는 하지 않기 에 bash가 합니다.shopt명령어를 사용합니다.

「」/「」를 할 수 goto

#!/bin/bash

shopt -s expand_aliases
if [ -n "$DEBUG" ] ; then
  alias goto="cat >/dev/null <<"
else
  alias goto=":"
fi

goto '#GOTO_1'

echo "Don't run this"

#GOTO1

echo "Run this"

goto '#GOTO_2'

echo "Don't run this either"

#GOTO_2

echo "All done"

에 이렇게 하면 요.export DEBUG=TRUE를 참조해 주세요.

이므로, 「코멘트」, 「코멘트」를 로 해도 하지 않습니다goto(설정(설정)에 의한goto:는 'no-op'이라는 'no-op', 'no-op', 'no-op', 'no-op', 'no-op', 'no-op', 'no-op', 'no-op', 'no-op', 'no-op', ', no-op, no-op', 'no-op, no-op, no-op, no, no-op, no, no, no-op,goto★★★★★★★★★★★★★★★★★★.

의 를 사용할 goto 방법:할 수 해야 합니다.위 위 중 해야 할 수 .이러한 정의는 스크립트의 맨 위 또는 맨 위 중 하나로 이동해야 할 수도 있습니다.goto★★★★★★★★★★★★★★★★★★.

은 이미 인 것은 gotobash의및 함수,등 대체 를하여 루프 bash를 하겠습니다.break는 특정 유형의 goto 문을 시뮬레이트할 수 있습니다.

이것이 가장 도움이 되는 것은 특정 조건이 충족되지 않을 경우 코드 섹션의 선두로 돌아가야 하는 경우입니다.다음 예에서는 while 루프는 테스트 IP로의 패킷 폐기가 정지될 때까지 계속 실행됩니다.

#!/bin/bash

TestIP="8.8.8.8"

# Loop forever (until break is issued)
while true; do

    # Do a simple test for Internet connectivity
    PacketLoss=$(ping "$TestIP" -c 2 | grep -Eo "[0-9]+% packet loss" | grep -Eo "^[0-9]")

    # Exit the loop if ping is no longer dropping packets
    if [ "$PacketLoss" == 0 ]; then
        echo "Connection restored"
        break
    else
        echo "No connectivity"
    fi
done

솔루션에는 다음과 같은 문제가 있었습니다.

  • 로로 の indis indis indis 、 indis 、 indis 、 indis indis 。:
  • label:로서

다음은 고정 shell-check버전(클린 및 POSIX 호환)입니다.


#!/bin/sh

# GOTO for bash, based upon https://stackoverflow.com/a/31269848/5353461
goto() {
  label=$1
  cmd=$(sed -En "/^[[:space:]]*#[[:space:]]*$label:[[:space:]]*#/{:a;n;p;ba};" "$0")
  eval "$cmd"
  exit
}

start=${1:-start}
goto "$start"  # GOTO start: by default

#start:#  Comments can occur after labels
echo start
goto end

  # skip: #  Whitespace is allowed
echo this is usually skipped

# end: #
echo end

결과를 수 더 입니다.명령어trap예를 들어 청소용으로 사용할 수 있습니다.

goto배쉬로

다음은 뒤로만 점프하는 지저분한 회피책입니다.

#!/bin/bash -e
trap '
echo I am
sleep 1
echo here now.
' EXIT

echo foo
goto trap 2> /dev/null
echo bar

출력:

$ ./test.sh 
foo
I am
here now.

이것은 그런 식으로 사용해서는 안 되고 교육적인 목적으로만 사용되어야 한다.이것이 기능하는 이유는 다음과 같습니다.

trap는 예외 처리를 사용하여 코드 흐름의 변경을 실현하고 있습니다., 「」는,trap 크 it it it it it it it it it it it it it it it it it it it " " "goto이 존재하지 않기 때문에 에러가 발생하고, 통상은 스크립트가 종료됩니다.는, 이 에러로 되고 있습니다.trap및 , 。2>/dev/null는 일반적으로 표시되는 오류 메시지를 숨깁니다.

이러한 goto 실장은 존재하지 않는 명령어(또는 기타 오류)는 동일한 트랩명령어를 실행하기 때문에 신뢰성이 높지 않습니다.특히, 어떤 라벨로 갈지 선택할 수 없습니다.


기본적으로 실제 시나리오에서는 goto 문장이 필요하지 않습니다.다른 장소에 랜덤하게 전화를 걸면 코드를 이해하기 어려워지기 때문에 중복됩니다.

번 하여 " " " "를 사용하도록 .continue ★★★★★★★★★★★★★★★★★」break.

코드가 반복되면 함수를 작성하고 원하는 횟수만큼 호출하는 것을 고려해 보십시오.

값에 코드가 할 필요가 , " "를 사용하는 것을 하십시오.case★★★★★★ 。

긴 코드를 더 작은 조각으로 분리할 수 있는 경우 다른 파일로 이동하여 상위 스크립트에서 호출하는 것을 고려해 보십시오.

저는 이 기능을 이용해서 하는 방법을 알아냈어요.

선택지가 있다, 3가지 선택지가 A,B , , , , 입니다.CA ★★★★★★★★★★★★★★★★★」BC자세한 내용은 를 참조하고 원래 프롬프트로 돌아갑니다.이것은 기능을 사용하여 수행할 수 있습니다.

에는 「」이 되어 있으므로 .function demoFunction 것뿐입니다.이 경우, 콜을 할 .전화 주세요.demoFunction이 스크립트가 끝나면 실제로 기능이 실행됩니다.

개 '어느 정도', '어느 정도', '어느 정도', '어느 정도', '어느 정도', '어느 정도', '어느 정도'가때 전화를 걸면쉽게 할 수 .GOTO셸 스크립트의 다른 장소.

function demoFunction {
        read -n1 -p "Pick a letter to run a command [A, B, or C for more info] " runCommand

        case $runCommand in
            a|A) printf "\n\tpwd being executed...\n" && pwd;;
            b|B) printf "\n\tls being executed...\n" && ls;;
            c|C) printf "\n\toption A runs pwd, option B runs ls\n" && demoFunction;;
        esac
}

demoFunction

이것은 Hubbitus가 올린 Judy Schmidt 대본의 작은 수정입니다.

스크립트에 이스케이프되지 않은 라벨을 삽입하면 머신에 문제가 발생하여 머신에 크래시가 발생하였습니다.이 문제는 #를 추가하여 라벨을 이스케이프하는 것으로 해결할 수 있습니다.Alexej Magura와 access_graved의 제안에 감사드립니다.

#!/bin/bash
# include this boilerplate
function goto {  
label=$1
cmd=$(sed -n "/$#label#:/{:a;n;p;ba};" $0 | grep -v ':$')
eval "$cmd"
exit
}

start=${1:-"start"}

goto $start

#start#
echo "start"
goto bing

#boom#
echo boom
goto eof

#bang#
echo bang
goto boom

#bing#
echo bing
goto bang

#eof#
echo "the end mother-hugger..."

디버깅 시 코멘트 아웃 코드 블록을 사용하기 위한 간단한 검색 가능 goto.

GOTO=false
if ${GOTO}; then
    echo "GOTO failed"
    ...
fi # End of GOTO
echo "GOTO done"

결과 -> GOTO 완료

'걸 때 '고토'를 게 제 예요.selectcase변수를 할당하면 if 문을 체크합니다.이 될 수 .

예:

#!/usr/bin/env bash

select goto in Ubuntu Debian Quit ; do
    case $goto in
        Ubuntu) { CHOICE="Ubuntu" ; break ; } ;;
        Debian) { CHOICE="Debian" ; break ; } ;;
        Quit)   { echo "Bye" ; exit ; } ;;
        *)      { echo "Invalid selection, please try again..." ; } ;;
    esac
done

if [ "$CHOICE" == "Ubuntu" ]; then
    echo "I'm in Ubuntu"
fi

if [ "$CHOICE" == "Debian" ]; then
    echo "I'm in Debian"
fi

직접 하지 않는
.

내 스타일:

#!/bin/bash

# Your functions
function1 ()
{
    commands
}

function2 ()
{
    commands
}
    :
    :

functionn ()
{
    commands
}

# Execute 1 to n in order
for i in {1..n}
    do
        function$i
    done

# with conditions
for i in {1..n}
    do
        [ condition$i ] && function$i
    done

# Random order
function1
functionn
function5
    :
    :
function3

위 스타일의 예:

#!/bin/bash

# Your functions
function1 ()
{
    echo "Task 1"
}

function2 ()
{
    echo "Task 2"
}

function3 ()
{
    echo "Task 3"
}

function1
function3
function2

출력:

Task 1
Task 3
Task 2

결점:

  • 조직적인 방법으로 스크립트를 작성합니다.
  • 문제가 적고 오류가 발생하기 쉽습니다.
  • 기존 기능 내에서 기능을 만들 수 있습니다.
  • 아무 문제 없이 앞뒤로 움직이세요.

언급URL : https://stackoverflow.com/questions/9639103/is-there-a-goto-statement-in-bash

반응형