development

Bash 함수에 매개 변수 전달

big-blog 2020. 9. 28. 09:34
반응형

Bash 함수에 매개 변수 전달


Bash 함수에서 매개 변수를 전달하는 방법을 검색하려고하는데 항상 명령 줄에서 매개 변수를 전달하는 방법이 나타납니다.

내 스크립트 내에서 매개 변수를 전달하고 싶습니다. 나는 시도했다 :

myBackupFunction("..", "...", "xx")

function myBackupFunction($directory, $options, $rootPassword) {
     ...
}

하지만 구문이 올바르지 않습니다. 내 함수에 매개 변수를 전달하는 방법은 무엇입니까?


함수를 선언하는 두 가지 일반적인 방법이 있습니다. 두 번째 접근 방식을 선호합니다.

function function_name {
   command...
} 

또는

function_name () {
   command...
} 

인수를 사용하여 함수를 호출하려면 :

function_name "$arg1" "$arg2"

함수는 전달 된 인수를 이름이 아닌 위치 (예 : $ 1, $ 2 등)로 참조합니다. $ 0 은 스크립트 자체의 이름입니다.

예:

function_name () {
   echo "Parameter #1 is $1"
}

또한 함수 가 선언 된 호출해야합니다 .

#!/usr/bin/env sh

foo 1  # this will fail because foo has not been declared yet.

foo() {
    echo "Parameter #1 is $1"
}

foo 2 # this will work.

산출:

./myScript.sh: line 2: foo: command not found
Parameter #1 is 2

참조 : 고급 Bash 스크립팅 가이드 .


높은 수준의 프로그래밍 언어 (C / C ++ / Java / PHP / Python / Perl ...)에 대한 지식은 bash 함수가 다른 언어에서와 같이 작동해야한다고 평신도에게 제안합니다. 대신 bash 함수는 셸 명령처럼 작동하며 셸 명령 (ls -l)에 옵션을 전달하는 것과 같은 방식으로 인수가 전달 될 것으로 예상합니다. 실제로 bash의 함수 인수위치 매개 변수 ( $1, $2..$9, ${10}, ${11}등) 로 처리됩니다 . getopts작동 방식을 고려하면 놀라운 일이 아닙니다 . bash에서 함수를 호출하는 데 괄호가 필요하지 않습니다.


( 참고 : 저는 현재 Open Solaris에서 작업하고 있습니다.)

# bash style declaration for all you PHP/JavaScript junkies. :-)
# $1 is the directory to archive
# $2 is the name of the tar and zipped file when all is done.
function backupWebRoot ()
{
    tar -cvf - $1 | zip -n .jpg:.gif:.png $2 - 2>> $errorlog &&
        echo -e "\nTarball created!\n"
}


# sh style declaration for the purist in you. ;-)
# $1 is the directory to archive
# $2 is the name of the tar and zipped file when all is done.
backupWebRoot ()
{
    tar -cvf - $1 | zip -n .jpg:.gif:.png $2 - 2>> $errorlog &&
        echo -e "\nTarball created!\n"
}


#In the actual shell script
#$0               $1            $2

backupWebRoot ~/public/www/ webSite.tar.zip

명명 된 매개 변수를 선호하는 경우 몇 가지 트릭을 사용하여 명명 된 매개 변수를 실제로 함수에 전달할 수 있습니다 (배열 및 참조를 전달할 수도 있음).

내가 개발 한 방법을 사용하면 다음과 같은 함수에 전달되는 명명 된 매개 변수를 정의 할 수 있습니다.

function example { args : string firstName , string lastName , integer age } {
  echo "My name is ${firstName} ${lastName} and I am ${age} years old."
}

인수에 @required 또는 @readonly로 주석을 달고, ... rest 인수를 만들고, 순차 인수에서 배열을 만들고 (예 :) string[4]선택적으로 여러 줄에 인수를 나열 할 수도 있습니다.

function example {
  args
    : @required string firstName
    : string lastName
    : integer age
    : string[] ...favoriteHobbies

  echo "My name is ${firstName} ${lastName} and I am ${age} years old."
  echo "My favorite hobbies include: ${favoriteHobbies[*]}"
}

즉, 매개 변수를 이름으로 호출 할 수있을뿐만 아니라 (더 읽기 쉬운 코어를 구성 함) 실제로 배열 (및 변수에 대한 참조)을 전달할 수 있습니다.이 기능은 bash 4.3에서만 작동합니다! 또한 매핑 된 변수는 $ 1 (및 기타)와 마찬가지로 모두 로컬 범위에 있습니다.

The code that makes this work is pretty light and works both in bash 3 and bash 4 (these are the only versions I've tested it with). If you're interested in more tricks like this that make developing with bash much nicer and easier, you can take a look at my Bash Infinity Framework, the code below is available as one of its functionalities.

shopt -s expand_aliases

function assignTrap {
  local evalString
  local -i paramIndex=${__paramIndex-0}
  local initialCommand="${1-}"

  if [[ "$initialCommand" != ":" ]]
  then
    echo "trap - DEBUG; eval \"${__previousTrap}\"; unset __previousTrap; unset __paramIndex;"
    return
  fi

  while [[ "${1-}" == "," || "${1-}" == "${initialCommand}" ]] || [[ "${#@}" -gt 0 && "$paramIndex" -eq 0 ]]
  do
    shift # first colon ":" or next parameter's comma ","
    paramIndex+=1
    local -a decorators=()
    while [[ "${1-}" == "@"* ]]
    do
      decorators+=( "$1" )
      shift
    done

    local declaration=
    local wrapLeft='"'
    local wrapRight='"'
    local nextType="$1"
    local length=1

    case ${nextType} in
      string | boolean) declaration="local " ;;
      integer) declaration="local -i" ;;
      reference) declaration="local -n" ;;
      arrayDeclaration) declaration="local -a"; wrapLeft= ; wrapRight= ;;
      assocDeclaration) declaration="local -A"; wrapLeft= ; wrapRight= ;;
      "string["*"]") declaration="local -a"; length="${nextType//[a-z\[\]]}" ;;
      "integer["*"]") declaration="local -ai"; length="${nextType//[a-z\[\]]}" ;;
    esac

    if [[ "${declaration}" != "" ]]
    then
      shift
      local nextName="$1"

      for decorator in "${decorators[@]}"
      do
        case ${decorator} in
          @readonly) declaration+="r" ;;
          @required) evalString+="[[ ! -z \$${paramIndex} ]] || echo \"Parameter '$nextName' ($nextType) is marked as required by '${FUNCNAME[1]}' function.\"; " >&2 ;;
          @global) declaration+="g" ;;
        esac
      done

      local paramRange="$paramIndex"

      if [[ -z "$length" ]]
      then
        # ...rest
        paramRange="{@:$paramIndex}"
        # trim leading ...
        nextName="${nextName//\./}"
        if [[ "${#@}" -gt 1 ]]
        then
          echo "Unexpected arguments after a rest array ($nextName) in '${FUNCNAME[1]}' function." >&2
        fi
      elif [[ "$length" -gt 1 ]]
      then
        paramRange="{@:$paramIndex:$length}"
        paramIndex+=$((length - 1))
      fi

      evalString+="${declaration} ${nextName}=${wrapLeft}\$${paramRange}${wrapRight}; "

      # continue to the next param:
      shift
    fi
  done
  echo "${evalString} local -i __paramIndex=${paramIndex};"
}

alias args='local __previousTrap=$(trap -p DEBUG); trap "eval \"\$(assignTrap \$BASH_COMMAND)\";" DEBUG;'

Miss out the parens and commas:

 myBackupFunction ".." "..." "xx"

and the function should look like this:

function myBackupFunction() {
   # here $1 is the first parameter, $2 the second etc.
}

I hope this example can help you. It takes two numbers from the user, feeds them to the function called add (in the very last line of the code), and add will sum them up and print them.

#!/bin/bash

read -p "Enter the first  value: " x
read -p "Enter the second value: " y

add(){
    arg1=$1 #arg1 gets to be the first  assigned argument (note there are no spaces)
    arg2=$2 #arg2 gets to be the second assigned argument (note there are no spaces)

    echo $(($arg1 + $arg2))
}

add x y #feeding the arguments

Thought I'd pipe in with mention of another way to pass named parameters to bash... passing by reference. This is supported as of bash 4.0

#!/bin/bash
function myBackupFunction(){ # directory options destination filename
local directory="$1" options="$2" destination="$3" filename="$4";
  echo "tar cz ${!options} ${!directory} | ssh root@backupserver \"cat > /mnt/${!destination}/${!filename}.tgz\"";
}

declare -A backup=([directory]=".." [options]="..." [destination]="backups" [filename]="backup" );

myBackupFunction backup[directory] backup[options] backup[destination] backup[filename];

An alternative syntax for bash 4.3 is using a nameref

Although the nameref is a lot more convenient in that it seamlessly dereferences, some older supported distros still ship an older version so I won't recommend it quite yet.


A simple example that will clear both during executing script or inside script while calling a function.

#!/bin/bash
echo "parameterized function example"
function print_param_value(){
    value1="${1}" # $1 represent first argument
    value2="${2}" # $2 represent second argument
    echo "param 1 is  ${value1}" #as string
    echo "param 2 is ${value2}"
    sum=$(($value1+$value2)) #process them as number
    echo "The sum of two value is ${sum}"
}
print_param_value "6" "4" #space sparted value
#you can also pass paramter durign executing script
print_param_value "$1" "$2" #parameter $1 and $2 during executing

#suppose our script name is param_example
# call like this 
# ./param_example 5 5
# now the param will be $1=5 and $2=5

참고URL : https://stackoverflow.com/questions/6212219/passing-parameters-to-a-bash-function

반응형