Bash関数でパラメーターを渡す方法を検索しようとしていますが、コマンドラインからパラメーターを渡す方法が常に表示されます。
スクリプト内でパラメーターを渡したいのですが。私は試した:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
しかし、構文が正しくありません。パラメーターを関数に渡す方法は?
Bash関数でパラメーターを渡す方法を検索しようとしていますが、コマンドラインからパラメーターを渡す方法が常に表示されます。
スクリプト内でパラメーターを渡したいのですが。私は試した:
myBackupFunction("..", "...", "xx")
function myBackupFunction($directory, $options, $rootPassword) {
...
}
しかし、構文が正しくありません。パラメーターを関数に渡す方法は?
回答:
関数を宣言する一般的な方法は2つあります。私は2番目のアプローチを好みます。
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
function name() {}
。たぶん前に「Enter」を{}
function
キーワードと()
。私の目標(コマンドラインではなく、ファイル内)は、わかりやすくすることであり、入力した文字数を減らすことではありませんfunction myBackupFunction() compound-statement
。
function
キーワードバージョンは拡張です。もう1つの形式は、すべてのPOSIX準拠シェルで機能します。
function
キーワードは古いkshファミリシェルでそれを導入し、最新のbashはそれを尊重しないことを保証していました(そのようなシェルでfunction
は、変数をデフォルトでローカルにしました; bashで) 、それはしません)。そのため、その使用は、kshの動作を知っていて、予期する可能性のある人にとっては、わかりやすさが低下します。wiki.bash-hackers.org/scripting/obsoleteを
高水準プログラミング言語(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
変数の名前を使用したい。ただこれをしなさい。
declare filename=$1 # declare gives you more options and limits variable scope
配列を関数に渡したいですか?
callingSomeFunction "${someArray[@]}" # Expands to all array elements.
関数内では、このように引数を処理します。
function callingSomeFunction ()
{
for value in "$@" # You want to use "$@" here, not "$*" !!!!!
do
:
done
}
値と配列を渡す必要がありますが、それでも関数内で「$ @」を使用しますか?
function linearSearch ()
{
declare myVar="$1"
shift 1 # removes $1 from the parameter list
for value in "$@" # Represents the remaining parameters.
do
if [[ $value == $myVar ]]
then
echo -e "Found it!\t... after a while."
return 0
fi
done
return 1
}
linearSearch $someStringValue "${someArray[@]}"
名前付きパラメーターを好む場合は、(いくつかのトリックを使用して)実際に名前付きパラメーターを関数に渡すことができます(配列と参照を渡すことも可能になります)。
私が開発したメソッドを使用すると、次のような関数に渡される名前付きパラメーターを定義できます。
function example { args : string firstName , string lastName , integer age } {
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
}
また、引数に@requiredまたは@readonlyとして注釈を付けたり、... rest引数を作成したり、(egを使用して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(およびその他)と同じようにローカルスコープ内にあります。
これを機能させるコードはかなり軽量で、bash 3とbash 4の両方で機能します(これらは私がテストした唯一のバージョンです)。このようなbashでの開発をより簡単に簡単にするトリックに興味がある場合は、私のBash Infinity Frameworkをご覧ください。以下のコードは、その機能の1つとして利用できます。
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;'
@var
、@reference
、@params
変数は?これについてもっと知るには、インターネットで何を調べればよいですか?
ucommon
と私のコードの間に関係はありません。あなたが言及した問題を引き起こす何らかのツールがインストールされている可能性がありますが、それが何であるかはわかりません。
かっことカンマを逃します:
myBackupFunction ".." "..." "xx"
関数は次のようになります。
function myBackupFunction() {
# here $1 is the first parameter, $2 the second etc.
}
この例がお役に立てば幸いです。これは、ユーザーから2つの数値を受け取り、それらをadd
(コードの最後の行にある)呼び出された関数に渡し、それらをadd
合計して出力します。
#!/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
スクリプトの実行中または関数の呼び出し中にスクリプト内をクリアする簡単な例。
#!/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
名前付きパラメーターをbashに渡す別の方法について言及し、参照で渡すと思います。これは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];
bash 4.3の代替構文はnamerefを使用することです
namerefはシームレスに逆参照するという点ではるかに便利ですが、一部の古いサポートされているディストリビューションは、 古いバージョンをためまだお勧めしません。