Shell if else语句(详解版)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell if else语句(详解版)相关的知识,希望对你有一定的参考价值。
参考技术A 最简单的用法就是只使用 if 语句,它的语法格式为:condition是判断条件,如果 condition 成立(返回“真”),那么 then 后边的语句将会被执行;如果 condition 不成立(返回“假”),那么不会执行任何语句。
注意,最后必须以fi来闭合,fi 就是 if 倒过来拼写。也正是有了 fi 来结尾,所以即使有多条语句也不需要用 包围起来。
如果你喜欢,也可以将 then 和 if 写在一行:
请注意 condition 后边的分号;,当 if 和 then 位于同一行的时候,这个分号是必须的,否则会有语法错误。
例如,使用 if 语句来比较两个数字的大小:
运行结果:
如果有两个分支,就可以使用 if else 语句,它的格式为:
如果 condition 成立,那么 then 后边的 statement1 语句将会被执行;否则,执行 else 后边的 statement2 语句。
例如:
运行结果:
从运行结果可以看出,a 和 b 不相等,判断条件不成立,所以执行了 else 后边的语句。
Shell 支持任意数目的分支,当分支比较多时,可以使用 if elif else 结构,它的格式为:
注意,if 和 elif 后边都得跟着 then。
整条语句的执行逻辑为:
如果 condition1 成立,那么就执行 if 后边的 statement1;如果 condition1 不成立,那么继续执行 elif,判断 condition2。
如果 condition2 成立,那么就执行 statement2;如果 condition2 不成立,那么继续执行后边的 elif,判断 condition3。
如果 condition3 成立,那么就执行 statement3;如果 condition3 不成立,那么继续执行后边的 elif。
如果所有的 if 和 elif 判断都不成立,就进入最后的 else,执行 statementn。
例如,,输入年龄,输出对应的人生阶段:
运行结果1:
运行结果2:
Shell - 检查 if/else 语句中是不是存在 git 标签
【中文标题】Shell - 检查 if/else 语句中是不是存在 git 标签【英文标题】:Shell - check if a git tag exists in an if/else statementShell - 检查 if/else 语句中是否存在 git 标签 【发布时间】:2013-07-21 08:07:15 【问题描述】:我正在为一个 zend 应用程序创建一个部署脚本。脚本几乎完成了,只是我想验证存储库中是否存在标签以强制团队添加标签。目前我有以下代码:
# First update the repo to make sure all the tags are in
cd /git/repo/path
git pull
# Check if the tag exists in the rev-list.
# If it exists output should be zero,
# else an error will be shown which will go to the else statement.
if [ -z "'cd /git/repo/path && git rev-list $1..'" ]; then
echo "gogo"
else
echo "No or no correct GIT tag found"
exit
fi
期待您的反馈!
更新
当我在命令行中执行以下操作时:
cd /git/repo/path && git rev-list v1.4..
我得到 NO 输出,这很好。虽然当我执行时:
cd /git/repo/path && git rev-list **BLA**..
我得到一个错误,这又是好事:
fatal: ambiguous argument 'BLA..': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions
语句中的 -z 表示,如果 sting 为空,则...换句话说,它可以通过命令行正常工作。虽然当我在语句中的 shell 脚本中使用相同的命令时,它似乎不起作用。
[ -z "'cd /git/repo/path && git rev-list $1..'" ]
这个方法灵感来自Validate if commit exists
更新 2
我发现了问题:
见Using if elif fi in shell scripts >
sh 将 && 解释为 shell 运算符。改成-a,就是 [的合取运算符:
[ "$arg1" = "$arg2" -a "$arg1" != "$arg3" ] 另外,您应该始终 引用变量,因为 [ 在您离开时会感到困惑 论据。
换句话说,我将&&
更改为;
并简化了条件。现在效果很好。
if cd /path/to/repo ; git rev-list $1.. >/dev/null
then
echo "gogo"
else
echo "WRONG"
exit
fi
【问题讨论】:
$sha
变量是否在别处定义?
另请注意,git pull
在更新引用后会进行合并,您需要改用git fetch
见Bash/Shell Script Function to Verify Git Tag or Commit Exists and Has Been Pushed to Remote Repository
好吧,让我再解释一下,请参阅说明中的更新。
我建议git rev-parse --verify refs/tags/$tagname
可能是更好的方法来做到这一点......(至少似乎是主要的git
在内部这样做......)。
【参考方案1】:
为什么这么复杂?这是一个非常简单的解决方案(基于页面下方的cad106uk’s approach):
version=1.2.3
if [ $(git tag -l "$version") ]; then
echo yes
else
echo no
fi
没有必要将git tag -l
的输出与版本号进行比较,因为如果找不到版本,输出将为空。因此,测试是否有任何输出就足够了。
注意:$version
周围的引号对于避免误报很重要。因为如果$version
出于某种原因为空,git tag -l
只会列出 所有 个标签,并且条件始终为真。
【讨论】:
是的,它也是:)【参考方案2】:您可以改用git rev-parse
:
if GIT_DIR=/path/to/repo/.git git rev-parse $1 >/dev/null 2>&1
then
echo "Found tag"
else
echo "Tag not found"
fi
git rev-list
调用图遍历,git rev-parse
会避免它。上面有一些可能查找对象而不是标签的问题。您可以通过在标签名称后使用^tag
来避免这种情况,但这仅适用于带注释的标签,不适用于轻量级标签:
if GIT_DIR=/path/to/repo/.git git rev-parse "$1^tag" >/dev/null 2>&1
then
echo "Found tag"
else
echo "Tag not found"
fi
@Lassi 还指出,如果您的标签名称以 -
开头,那么它可能会被解释为一个选项。您可以通过查找 refs/tags/$1
来避免该问题。所以总而言之,使用rev-parse
版本,您可以查找refs/tags/$1
来获取轻量级和带注释的标签,您可以在末尾附加^tag
以强制执行带注释的标签(refs/tags/$1^tag
)。
另外,正如@forvaidya 之前提到的,你可以简单地列出你想要的标签和grep:
if GIT_DIR=/path/to/repo/.git git show-ref --tags | egrep -q "refs/tags/$1$"
then
echo "Found tag"
else
echo "Tag not found"
fi
您也可以使用git tag --list
代替git show-ref --tags
:
if GIT_DIR=/path/to/repo/.git git tag --list | egrep -q "^$1$"
then
echo "Found tag"
else
echo "Tag not found"
fi
如果您知道标签,我认为最好通过rev-parse
查找它。我不喜欢egrep
版本的一件事是,您可能拥有可能被解释为正则表达式序列并导致误报或误报的字符。 rev-parse
版本在这个意义上更胜一筹,因为它不会查看整个标签列表。
另一种选择是使用git show-ref
的模式特征:
if GIT_DIR=/path/to/repo/.git git show-ref --tags "refs/tags/$1" >/dev/null 2>&1
then
echo "Found tag"
else
echo "Tag not found"
fi
这避免了额外的egrep
调用,并且更直接。
【讨论】:
是的,定义 GIT_DIR 是个好方法!我认为他们都工作。还是谢谢。rev-parse
选项将匹配 Git “长”标签(由 git describe
生成),但第二个选项仅匹配真实标签。谢谢!不过,我认为使用git show-ref --tags
比使用git tag --list
没有任何优势。有关系吗?
@big_m 没关系。你只需要确保正确匹配它......所以使用类似egrep -q "^$1$"
的东西来匹配确保你匹配整个条目。
@big_m 我用一个额外的块更新了答案,展示了如何使用rev-parse
版本只查找标签。
感谢^tag
后缀提示,@jszakmeister!我可以发誓我试过了,但显然没有(或者无论如何都不正确)。我刚刚又试了一次,果然如你所说。【参考方案3】:
这是进一步开发的 rev-parse 版本:
tag=whatever
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null; then
echo "found"
else
echo "not found"
fi
它看起来很健壮:
仅检查标记,而不检查分支或提交哈希等。 奇怪的标签名称输入不会导致奇怪的行为: 以“-”开头的标记名称不会被误认为是命令行选项 包含斜线或点的标记名称并不特殊 包含空格的标记名称并不特殊 空白标签名称并不特殊【讨论】:
不幸的是,如果 $tag 字符串以“-q”和 7 个或更多十六进制数字的字符串结尾(例如在从git describe
生成的“long”标签中),这将匹配提交哈希,即使没有这样的标签。 git tag --list
或 git show-ref --tags
的 grep 选项是我发现的唯一可以避免这种情况的选项。【参考方案4】:
非常简单的版本(使用 git ls-remote)
TAG_NAME=$1
git ls-remote --exit-code --tags origin $TAG_NAME || echo 'not found'
【讨论】:
【参考方案5】:我认为我非常喜欢的解决方案是使用更现代的 git 版本(git 版本 2.7.4)
#!/usr/bin/env bash
cd /to/repo/base;
tagName="Whatever";
if [[ `git tag -l $tagName` == $tagName ]]; then
echo "yes";
else
echo "no";
fi
【讨论】:
【参考方案6】:假设您在项目根目录中...
# Filename: check-for-tag
# Usage: check-for-tag <TAG_NAME>
# Example: check-for-tag ticket-123-fix-this-bug
TAG_NAME=$1
git ls-remote --tags 2>/dev/null | grep $TAG_NAME 1>/dev/null
if [ "$?" == 0 ]; then
echo "Git tag $TAG_NAME exists."
else
echo "Git tag $TAG_NAME does not exist."
fi
【讨论】:
如果你想知道确切的标签是否存在,你可以运行git ls-remote --tags 2>/dev/null | grep "refs/tags/$TAG_NAME$" 1>/dev/null
。【参考方案7】:
我使用这种方法来判断当前版本是否存在标记,以避免标记两次。
git_rev_id=$(git -C $REPO_FOLDER rev-parse HEAD)
git_tags=$(git tag)
for git_tag in $git_tags; do
git_temp_tag=$(git cat-file tag $git_tag | grep $git_rev_id);
if [ -z "$git_temp_tag" ]
then
false; #do nothing
else
git_tag_exists=$git_tag
fi
done
if [ -z "$git_tag_exists" ]
then
echo "need to make a tag"
else
echo "Found tag: $git_tag_exits"
fi
【讨论】:
以上是关于Shell if else语句(详解版)的主要内容,如果未能解决你的问题,请参考以下文章