有时我会定义一个函数来隐藏可执行文件并调整其参数或输出。因此该函数与可执行文件具有相同的名称,我需要一种如何从该函数运行可执行文件而不递归调用该函数的方法。例如,要自动运行的输出fossil diff通过colordiff与less -R使用:
function fossil () {
local EX=$(which fossil)
if [ -z "$EX" ] ; then
echo "Unable to find 'fossil' executable." >&2
return 1
fi
if [ -t 1 ] && [ "$1" == "diff" ] ; then
"$EX" "$@" | colordiff | less -R
return
fi
"$EX" "$@"
}
Run Code Online (Sandbox Code Playgroud)
如果我确定可执行文件的位置,我可以简单地输入/usr/bin/fossil. Bash 认识到这/意味着它是一个可执行文件,而不是一个函数。但由于我不知道确切的位置,我不得不求助于调用which并检查结果。有没有更简单的方法?
我bash在我的~/.bashrc文件中定义了一个函数。这允许我在 shell 终端中使用它。但是,当我从脚本中调用它时,它似乎不存在。
如何定义bash脚本也使用的函数?
我想在 Bash 中实现一个函数,它在每次调用时增加(并返回)一个计数。不幸的是,这似乎很重要,因为我在子 shell 中调用该函数,因此它无法修改其父 shell 的变量。
这是我的尝试:
PS_COUNT=0
ps_count_inc() {
let PS_COUNT=PS_COUNT+1
echo $PS_COUNT
}
ps_count_reset() {
let PS_COUNT=0
}
Run Code Online (Sandbox Code Playgroud)
这将按如下方式使用(因此我需要从子shell调用函数):
PS1='$(ps_count_reset)> '
PS2='$(ps_count_inc) '
Run Code Online (Sandbox Code Playgroud)
这样,我就会有一个带编号的多行提示:
> echo 'this
1 is
2 a
3 test'
Run Code Online (Sandbox Code Playgroud)
可爱的。但由于上述限制不起作用。
一个无效的解决方案是将计数写入文件而不是变量。但是,这会在多个同时运行的会话之间产生冲突。当然,我可以将 shell 的进程 ID 附加到文件名。但我希望有一个更好的解决方案,不会让我的系统因大量文件而混乱。
我有一个 bash 脚本,如下所示,它安装了 zookeeper,但前提是尚未安装。
##zookeper
installZook(){
ZOOK_VERSION="3.4.5"
ZOOK_TOOL="zookeeper-${ZOOK_VERSION}"
ZOOK_DOWNLOAD_URL="http://www.us.apache.org/dist/zookeeper/${ZOOK_TOOL}/${ZOOK_TOOL}.tar.gz"
if [ -e $DEFAULT_INSTALLATION_DEST/${ZOOK_TOOL} ]; then
echo "${ZOOK_TOOL} alreay installed";
exit 1; # <<<< here
elif [ ! -e $DEFAULT_SOURCE_ROOT/${ZOOK_TOOL}.tar.gz ]; then
wgetIt $ZOOK_DOWNLOAD_URL
else
echo "[info] : $DEFAULT_SOURCE_ROOT/$ZOOK_TOOL already exists"
fi
sudo mkdir -p /var/lib/zookeeper
sudo mkdir -p /var/log/zookeeper
tarIt "$DEFAULT_SOURCE_ROOT/$ZOOK_TOOL.tar.gz"
sudo chmod 777 -R $DEFAULT_INSTALLATION_DEST/$ZOOK_TOOL
cp $DEFAULT_INSTALLATION_DEST/$ZOOK_TOOL/conf/zoo_sample.cfg $DEFAULT_INSTALLATION_DEST/$ZOOK_TOOL/conf/zoo.cfg
cat >> ~/.bash_profile <<'EOF'
###############################
########### ZOOK ###############
###############################
ZOOK_HOME=/usr/local/zookeper-3.4.5
export ZOOK_HOME
export PATH=$PATH:$ZOOK_HOME/bin
EOF
}
Run Code Online (Sandbox Code Playgroud)
在标记为 的行<<<< here,如果已经安装了 …
我使用带有本机 Bash 的 Ubuntu 16.04。
我不确定是否执行
#!/bin/bash
myFunc() {
export myVar="myVal"
}
myFunc
Run Code Online (Sandbox Code Playgroud)
在任何意义上都等于,只是执行export myVar="myVal".
当然,全局变量通常应该在函数之外声明(我认为这是约定俗成的问题,即使技术上可行)但我确实想知道更奇特的情况,即编写一些非常通用的函数并希望在其中添加一个变量仍然可以在任何地方使用。
将export一个函数中的变量,等同于全球出口了,直接在命令行,使其可用于一切都在外壳(所有子shell,以及功能在其内部)?
我有一个功能可以快速创建一个新的 SVN 分支,看起来像这样
function svcp() { svn copy "repoaddress/branch/$1.0.x" "repoaddress/branch/dev/$2" -m "dev branch for $2"; }
Run Code Online (Sandbox Code Playgroud)
我用它来快速创建一个新分支,而无需查找和复制粘贴地址和其他一些东西。但是,对于消息(-m 选项),我想要它,以便如果我提供第三个参数,则将其用作消息,否则使用“dev branch for $2”的“默认”消息。有人可以解释这是如何完成的吗?
有没有办法测试是否存在同时适用于bash和的shell 函数zsh?
在 python 中,我们可以使用自动应用和针对函数执行的代码来装饰函数。
bash 中是否有类似的功能?
在我目前正在处理的脚本中,我有一些样板文件来测试所需的参数并在它们不存在时退出 - 如果指定了调试标志,则显示一些消息。
不幸的是,我必须将这段代码重新插入到每个函数中,如果我想更改它,我将不得不修改每个函数。
有没有办法从每个函数中删除此代码并将其应用于所有函数,类似于 python 中的装饰器?
数据
1
\begin{document}
3
Run Code Online (Sandbox Code Playgroud)
代码
#!/bin/bash
function getStart {
local START="$(awk '/begin\{document\}/{ print NR; exit }' data.tex)"
echo $START
}
START2=$(getStart)
echo $START2
Run Code Online (Sandbox Code Playgroud)
返回2但我想要3. 我在这个关于如何在 bash 脚本中添加数字的答案中最终更改失败:
START2=$((getStart+1))
Run Code Online (Sandbox Code Playgroud)
如何在 Bash 脚本中增加局部变量?
为什么不在这个简单的 bash 脚本中echo $1打印$1?
#!/bin/bash
# function.sh
print_something () {
echo $1
}
print_something
$ ./function.sh 123 -> why doesn't it print '123' as a result?
Run Code Online (Sandbox Code Playgroud)