Shell: 以参数作为函数参数传递函数
Shell: Pass function with arguments as function argument
我正在开发一个 shell 程序来自动化我的 Arch(强制性 btw)安装。为了使其更具交互性,我构建了以下函数:
# READYN
# ARGS:
# - Yes/no question
# - Command to run if yes
# - Command to run if no
#
# Prompts the user with a yes/no question (with precedence for yes) and
# run an order if the answer is yes or another if it's no.
readyn () {
while :
do
local yn;
printf "%s? [Y/n]: " "";
read yn;
if [[ "$yn" =~ ^([yY][eE][sS]|[yY])?$ ]]; then
;
break;
elif [[ "$yn" =~ ^([nN][oO]|[nN])+$ ]]; then
;
break;
fi
done
}
我已经成功 传递了一个 "echo Hello World!"
作为参数并拥有它 运行。我还能够传递另一个函数。例如:
yayprompt () {
printf "yay is required to install %s.\n" ""
readyn "Install yay, the AUR manager" "yayinstall" ""
}
如果是,则调用 yayinstall
,如果不是,则不执行任何操作。
我的问题来自于更复杂的函数,这些函数作为参数传递但要么未被识别,要么 运行 在不应该的情况下被识别。问题来自以下功能:
# MANAGEPGK
# ARGS:
# - Package name
# - Package variable
# - Yay required
#
# Checks if the package is added to the pkglist to either add or remove it.
# If yay is required to install it, it prompts the user whether they wish
# to install yay or don't install the package (if yay is not installed).
# This functions DOES NOT prompt any installation options on the user. To
# do this, use PROMPTPKG.
managepkg () {
local pkgvar=
if [ $pkgvar == 0 ]; then
if [ == 1 ] && [ $yay == 0 ]; then
yayprompt;
fi
if [ == 0 ] || [ $yay == 1 ]; then
addpkg "";
pkgvar=1;
fi
else
rmpkg "";
pkgvar=0;
fi
echo "$pkgvar";
}
为了使其正常工作,必须(或者至少我必须)这样调用它:
dewm_cinnamon=$(managepkg cinnamon $dewm_cinnamon 0)
现在,我试图将它作为参数传递给 readyn
,但我根据格式得到这些输出(我总是将 yes
回答为空字符串:
单引号:
readyn "Install gaps" \
'dewm_i3gaps=$(managepkg i3-gaps $dewm_i3gaps 0)' \
'dewm_i3=$(managepkg i3-wm $dewm_i3 0)';
Install gaps? [Y/n]:
./architup.sh: line 341: dewm_i3gaps=$(managepkg: command not found
双引号:
readyn "Install gaps" \
"dewm_i3gaps=$(managepkg i3-gaps $dewm_i3gaps 0)" \
"dewm_i3=$(managepkg i3-wm $dewm_i3 0)";
Install gaps? [Y/n]:
./architup.sh: line 341: dewm_i3gaps=1: command not found
美元封闭:(这个 运行 两个命令如 cat pkglist
中所示)
readyn "Install gaps" \
$(dewm_i3gaps=$(managepkg i3-gaps $dewm_i3gaps 0)) \
$(dewm_i3=$(managepkg i3-wm $dewm_i3 0));
Install gaps? [Y/n]:
Install compton? [Y/n]: ^C
Documents/Repositories/architup took 5s
➜ cat pkglist
i3-gaps
i3-wm
我应该使用什么语法来使readyn
运行只有一个基于用户输入的命令?
谢谢!
函数参数只是字符串。恕我直言,一个更好的设计是简单地让 readyn
return 为 "yes" 为真(零),否则为假,并让调用代码基于此实现任何条件逻辑。
readyn () {
read -p "$@"
case $REPLY in
[Yy] | [Yy][Ee][Ss]) return 0;;
esac
return 1
}
readyn "Are you ready San Antonio?" &&
rock and roll
if readyn "Let me hear you say yeah"; then
echo "Let's go!"
else
echo "If you feel mellow, get outta here"
fi
(对各地的摇滚音乐会表示歉意,)
我正在开发一个 shell 程序来自动化我的 Arch(强制性 btw)安装。为了使其更具交互性,我构建了以下函数:
# READYN
# ARGS:
# - Yes/no question
# - Command to run if yes
# - Command to run if no
#
# Prompts the user with a yes/no question (with precedence for yes) and
# run an order if the answer is yes or another if it's no.
readyn () {
while :
do
local yn;
printf "%s? [Y/n]: " "";
read yn;
if [[ "$yn" =~ ^([yY][eE][sS]|[yY])?$ ]]; then
;
break;
elif [[ "$yn" =~ ^([nN][oO]|[nN])+$ ]]; then
;
break;
fi
done
}
我已经成功 传递了一个 "echo Hello World!"
作为参数并拥有它 运行。我还能够传递另一个函数。例如:
yayprompt () {
printf "yay is required to install %s.\n" ""
readyn "Install yay, the AUR manager" "yayinstall" ""
}
如果是,则调用 yayinstall
,如果不是,则不执行任何操作。
我的问题来自于更复杂的函数,这些函数作为参数传递但要么未被识别,要么 运行 在不应该的情况下被识别。问题来自以下功能:
# MANAGEPGK
# ARGS:
# - Package name
# - Package variable
# - Yay required
#
# Checks if the package is added to the pkglist to either add or remove it.
# If yay is required to install it, it prompts the user whether they wish
# to install yay or don't install the package (if yay is not installed).
# This functions DOES NOT prompt any installation options on the user. To
# do this, use PROMPTPKG.
managepkg () {
local pkgvar=
if [ $pkgvar == 0 ]; then
if [ == 1 ] && [ $yay == 0 ]; then
yayprompt;
fi
if [ == 0 ] || [ $yay == 1 ]; then
addpkg "";
pkgvar=1;
fi
else
rmpkg "";
pkgvar=0;
fi
echo "$pkgvar";
}
为了使其正常工作,必须(或者至少我必须)这样调用它:
dewm_cinnamon=$(managepkg cinnamon $dewm_cinnamon 0)
现在,我试图将它作为参数传递给 readyn
,但我根据格式得到这些输出(我总是将 yes
回答为空字符串:
单引号:
readyn "Install gaps" \
'dewm_i3gaps=$(managepkg i3-gaps $dewm_i3gaps 0)' \
'dewm_i3=$(managepkg i3-wm $dewm_i3 0)';
Install gaps? [Y/n]:
./architup.sh: line 341: dewm_i3gaps=$(managepkg: command not found
双引号:
readyn "Install gaps" \
"dewm_i3gaps=$(managepkg i3-gaps $dewm_i3gaps 0)" \
"dewm_i3=$(managepkg i3-wm $dewm_i3 0)";
Install gaps? [Y/n]:
./architup.sh: line 341: dewm_i3gaps=1: command not found
美元封闭:(这个 运行 两个命令如 cat pkglist
中所示)
readyn "Install gaps" \
$(dewm_i3gaps=$(managepkg i3-gaps $dewm_i3gaps 0)) \
$(dewm_i3=$(managepkg i3-wm $dewm_i3 0));
Install gaps? [Y/n]:
Install compton? [Y/n]: ^C
Documents/Repositories/architup took 5s
➜ cat pkglist
i3-gaps
i3-wm
我应该使用什么语法来使readyn
运行只有一个基于用户输入的命令?
谢谢!
函数参数只是字符串。恕我直言,一个更好的设计是简单地让 readyn
return 为 "yes" 为真(零),否则为假,并让调用代码基于此实现任何条件逻辑。
readyn () {
read -p "$@"
case $REPLY in
[Yy] | [Yy][Ee][Ss]) return 0;;
esac
return 1
}
readyn "Are you ready San Antonio?" &&
rock and roll
if readyn "Let me hear you say yeah"; then
echo "Let's go!"
else
echo "If you feel mellow, get outta here"
fi
(对各地的摇滚音乐会表示歉意,)