쉘 스크립트의 다른 함수에서 선언/초기화된 변수를 `에코`하는 방법은 무엇입니까?

쉘 스크립트의 다른 함수에서 선언/초기화된 변수를 `에코`하는 방법은 무엇입니까?

Ubuntu 14.04.1에서 이것을 실행하십시오.

./script.sh MyVM take

echo함수의 줄은 list_snapshot작동하지만(3개 변수의 값을 인쇄함) echo안의 줄은 take_snapshot변수의 값을 인쇄할 수 없고 $output$old_snapshot_name값만 인쇄할 수 있는 이유는 무엇입니까 $machine_name?

를 실행하면 스크립트가 작동 ./script.sh MyVM take하고 이전 스냅샷을 삭제하고 새 스냅샷을 생성합니다.

#! /bin/sh

if [ ! "$1" ]; then
    echo "Usage: $0 <vmname> list|take"
    exit 1
else
    machine_name=$1
fi

list_snapshot () {
    output=$(VBoxManage snapshot "$machine_name" list)
    count=$(echo "$output" | grep -c 'UUID')

    echo "Machine '$machine_name' has '$count' snapshots: \n '$output'"
    return "$count"
}


take_snapshot () {
    echo "$output"
    while (list_snapshot; [ $? -gt 3 ])  
    do
        old_snapshot_name=$(echo "$output" | grep -o 'UUID: (.{36})' | head -1)
        echo "Deleting old snapshot '$old_snapshot_name' for machine '$machine_name'..."

        VBoxManage snapshot "$machine_name" delete "$old_snapshot_name"

    done

    current_time=$(date "+%Y.%m.%d-%H.%M.%S")
    snapshot_name=$machine_name.$current_time

    echo "Taking new snapshot '$snapshot_name' for machine '$machine_name'..."
    VBoxManage snapshot "$machine_name" take "$snapshot_name" --live 
}

case "$2" in
  list)
    list_snapshot
    ;;
  take)
    take_snapshot
    ;;
  *)
    echo "Usage: $0 <vmname> list|take"
    exit 1
    ;;
esac

-x:없이 출력./snapshotVM.sh RancherOS-tools take

Machine 'RancherOS-tools' has '4' snapshots: 
 '   Name: RancherOS-tools.2015.11.03-11.25.12 (UUID: 7afef8ee-1915-4494-9634-add82e1a613f)
      Name: RancherOS-tools.2015.11.03-11.25.40 (UUID: 79a53543-377e-4a74-80ca-751883a7787b)
         Name: RancherOS-tools.2015.11.03-11.32.10 (UUID: 25a942fe-2d0a-4290-a98e-7d16ec4c60bd)
            Name: RancherOS-tools.2015.11.03-11.34.58 (UUID: 02af926b-396c-4ce6-bfb3-5e953de5a051) *'
Deleting old snapshot '' for machine 'RancherOS-tools'...
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Machine 'RancherOS-tools' has '3' snapshots: 
 '   Name: RancherOS-tools.2015.11.03-11.25.40 (UUID: 79a53543-377e-4a74-80ca-751883a7787b)
      Name: RancherOS-tools.2015.11.03-11.32.10 (UUID: 25a942fe-2d0a-4290-a98e-7d16ec4c60bd)
         Name: RancherOS-tools.2015.11.03-11.34.58 (UUID: 02af926b-396c-4ce6-bfb3-5e953de5a051) *'
Taking new snapshot 'RancherOS-tools.2015.11.03-11.35.20' for machine 'RancherOS-tools'...
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Snapshot taken. UUID: 5195881b-113b-448a-81e3-98a121c8fbfe

다음으로 출력 -x:./snapshotVM.sh RancherOS-tools take

dy@dy:~$ ./snapshotVM.sh RancherOS-tools take
+ [ ! RancherOS-tools ]
+ machine_name=RancherOS-tools
+ take_snapshot
+ echo 

+ list_snapshot
+ VBoxManage snapshot RancherOS-tools list
+ output=   Name: RancherOS-tools.2015.11.03-11.25.40 (UUID: 79a53543-377e-4a74-80ca-751883a7787b)
      Name: RancherOS-tools.2015.11.03-11.32.10 (UUID: 25a942fe-2d0a-4290-a98e-7d16ec4c60bd)
         Name: RancherOS-tools.2015.11.03-11.34.58 (UUID: 02af926b-396c-4ce6-bfb3-5e953de5a051)
            Name: RancherOS-tools.2015.11.03-11.35.20 (UUID: 5195881b-113b-448a-81e3-98a121c8fbfe) *
+ echo    Name: RancherOS-tools.2015.11.03-11.25.40 (UUID: 79a53543-377e-4a74-80ca-751883a7787b)
      Name: RancherOS-tools.2015.11.03-11.32.10 (UUID: 25a942fe-2d0a-4290-a98e-7d16ec4c60bd)
         Name: RancherOS-tools.2015.11.03-11.34.58 (UUID: 02af926b-396c-4ce6-bfb3-5e953de5a051)
            Name: RancherOS-tools.2015.11.03-11.35.20 (UUID: 5195881b-113b-448a-81e3-98a121c8fbfe) *
+ grep -c UUID
+ count=4
+ echo Machine 'RancherOS-tools' has '4' snapshots: \n '   Name: RancherOS-tools.2015.11.03-11.25.40 (UUID: 79a53543-377e-4a74-80ca-751883a7787b)
      Name: RancherOS-tools.2015.11.03-11.32.10 (UUID: 25a942fe-2d0a-4290-a98e-7d16ec4c60bd)
         Name: RancherOS-tools.2015.11.03-11.34.58 (UUID: 02af926b-396c-4ce6-bfb3-5e953de5a051)
            Name: RancherOS-tools.2015.11.03-11.35.20 (UUID: 5195881b-113b-448a-81e3-98a121c8fbfe) *'
Machine 'RancherOS-tools' has '4' snapshots: 
 '   Name: RancherOS-tools.2015.11.03-11.25.40 (UUID: 79a53543-377e-4a74-80ca-751883a7787b)
      Name: RancherOS-tools.2015.11.03-11.32.10 (UUID: 25a942fe-2d0a-4290-a98e-7d16ec4c60bd)
         Name: RancherOS-tools.2015.11.03-11.34.58 (UUID: 02af926b-396c-4ce6-bfb3-5e953de5a051)
            Name: RancherOS-tools.2015.11.03-11.35.20 (UUID: 5195881b-113b-448a-81e3-98a121c8fbfe) *'
+ return 4
+ [ 4 -gt 3 ]
+ echo 
+ head -1
+ grep -o UUID: (.{36})
+ old_snapshot_name=
+ echo Deleting old snapshot '' for machine 'RancherOS-tools'...
Deleting old snapshot '' for machine 'RancherOS-tools'...
+ VBoxManage snapshot RancherOS-tools delete 
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
+ list_snapshot
+ VBoxManage snapshot RancherOS-tools list
+ output=   Name: RancherOS-tools.2015.11.03-11.32.10 (UUID: 25a942fe-2d0a-4290-a98e-7d16ec4c60bd)
      Name: RancherOS-tools.2015.11.03-11.34.58 (UUID: 02af926b-396c-4ce6-bfb3-5e953de5a051)
         Name: RancherOS-tools.2015.11.03-11.35.20 (UUID: 5195881b-113b-448a-81e3-98a121c8fbfe) *
+ echo    Name: RancherOS-tools.2015.11.03-11.32.10 (UUID: 25a942fe-2d0a-4290-a98e-7d16ec4c60bd)
      Name: RancherOS-tools.2015.11.03-11.34.58 (UUID: 02af926b-396c-4ce6-bfb3-5e953de5a051)
         Name: RancherOS-tools.2015.11.03-11.35.20 (UUID: 5195881b-113b-448a-81e3-98a121c8fbfe) *
+ grep -c UUID
+ count=3
+ echo Machine 'RancherOS-tools' has '3' snapshots: \n '   Name: RancherOS-tools.2015.11.03-11.32.10 (UUID: 25a942fe-2d0a-4290-a98e-7d16ec4c60bd)
      Name: RancherOS-tools.2015.11.03-11.34.58 (UUID: 02af926b-396c-4ce6-bfb3-5e953de5a051)
         Name: RancherOS-tools.2015.11.03-11.35.20 (UUID: 5195881b-113b-448a-81e3-98a121c8fbfe) *'
Machine 'RancherOS-tools' has '3' snapshots: 
 '   Name: RancherOS-tools.2015.11.03-11.32.10 (UUID: 25a942fe-2d0a-4290-a98e-7d16ec4c60bd)
      Name: RancherOS-tools.2015.11.03-11.34.58 (UUID: 02af926b-396c-4ce6-bfb3-5e953de5a051)
         Name: RancherOS-tools.2015.11.03-11.35.20 (UUID: 5195881b-113b-448a-81e3-98a121c8fbfe) *'
+ return 3
+ [ 3 -gt 3 ]
+ date +%Y.%m.%d-%H.%M.%S
+ current_time=2015.11.03-11.37.46
+ snapshot_name=RancherOS-tools.2015.11.03-11.37.46
+ echo Taking new snapshot 'RancherOS-tools.2015.11.03-11.37.46' for machine 'RancherOS-tools'...
Taking new snapshot 'RancherOS-tools.2015.11.03-11.37.46' for machine 'RancherOS-tools'...
+ VBoxManage snapshot RancherOS-tools take RancherOS-tools.2015.11.03-11.37.46 --live
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Snapshot taken. UUID: 0e11c8d0-130c-4508-a2be-8692fc9316bd

업데이트: 코드를 다시 디자인하고 while 루프를 제거한 후 변수 범위 문제가 발생한 것 같습니다. 이제 작동합니다.

#! /bin/sh

# usage: 
# $0 <vmname> list : list all snapshot
# $0 <vmname> take : delete old snapshot name startwith "Backup" and leave 3 "Backup" snapshot

#set -x

if [ ! "$1" ]; then
    echo "Usage: $0 <vmname> list|take"
    exit 1
else
    machine_name=$1
fi

list_snapshot () {
    output=$(VBoxManage snapshot "$machine_name" list)
    count=$(echo "$output" | grep -c 'UUID')

    echo "Machine $machine_name has $count snapshots: "
    echo "$output"
}


take_snapshot () {
    output=$(VBoxManage snapshot "$machine_name" list)
    count=$(echo "$output" | grep -c 'Backup')

    echo "Machine $machine_name has $count snapshots: "
    echo "$output"

    if [ "$count" -ge 3 ]; then
        old_snapshots_uuid=$(echo "$output" | grep "Backup" | grep -Eo 'UUID: .{36}' | cut -c 7-42 | head -$((count-2)))

        for u in $old_snapshots_uuid; do
          echo "Deleting old snapshot $u for machine $machine_name..."
          VBoxManage snapshot "$machine_name" delete "$u"
        done    
    fi

    current_time=$(date "+%Y.%m.%d-%H.%M.%S")
    snapshot_name="Backup".$machine_name.$current_time

    echo "Taking new snapshot $snapshot_name for machine $machine_name..."
    VBoxManage snapshot "$machine_name" take "$snapshot_name"     
}

case "$2" in
  list)
    list_snapshot
    ;;
  take)
    take_snapshot
    ;;
  *)
    echo "Usage: $0 <vmname> list|take"
    exit 1
    ;;
esac

답변1

당신은 할 수 없습니다; 함수에서 선언/초기화된 변수는 해당 함수 범위에서만 볼 수 있습니다.

또한 특정 경우에 실행하면 ./script.sh MyVM take실행 list_snapshot()되지 않습니다. 어떻게 output선언/초기화되어야 합니까? ( old_snapshot_name선언/초기화가 선언/초기화 output되지 않은 에 의존하기 때문에 어떻게 선언/초기화되어야 합니까?)

output어떤 함수가 실제로 실행되는지에 관계없이 모든 함수에 표시 되도록 하려면 해당 선언/초기화를 외부로 이동합니다 list_snapshot()(예: take_snapshot()의 정의 뒤).

#! /bin/sh

if [ ! "$1" ]; then
    echo "Usage: $0 <vmname> list|take"
    exit 1
else
    machine_name=$1
fi

list_snapshot () {
    count=$(echo "$output" | grep -c 'UUID')

    echo "Machine '$machine_name' has '$count' snapshots: \n '$output'"
    return "$count"
}


take_snapshot () {
    echo "$output"
    while (list_snapshot; [ $? -gt 3 ])  
    do
        old_snapshot_name=$(echo "$output" | grep -o 'UUID: (.{36})' | head -1)
        echo "Deleting old snapshot '$old_snapshot_name' for machine '$machine_name'..."

        VBoxManage snapshot "$machine_name" delete "$old_snapshot_name"

    done

    current_time=$(date "+%Y.%m.%d-%H.%M.%S")
    snapshot_name=$machine_name.$current_time

    echo "Taking new snapshot '$snapshot_name' for machine '$machine_name'..."
    VBoxManage snapshot "$machine_name" take "$snapshot_name" --live 
}

output=$(VBoxManage snapshot "$machine_name" list)

case "$2" in
  list)
    list_snapshot
    ;;
  take)
    take_snapshot
    ;;
  *)
    echo "Usage: $0 <vmname> list|take"
    exit 1
    ;;
esac

관련 정보