Bash同时输入if和else语句
这里是上下文:我正在制作一个小的Linux命令,以便在创建C程序时自动创建基本代码。 我的命令名为Bash同时输入if和else语句,bash,Bash,这里是上下文:我正在制作一个小的Linux命令,以便在创建C程序时自动创建基本代码。 我的命令名为ctouch:它类似于touch命令,但在创建文件后,它还创建了C程序的基本结构: #include <stdio.h> #include <stdlib.h> int main(){ return 0: } #包括 #包括 int main(){ 返回0: } 附加这些行是有效的。这是我的密码: #! /bin/bash for arg in "$@"
ctouch
:它类似于touch
命令,但在创建文件后,它还创建了C程序的基本结构:
#include <stdio.h>
#include <stdlib.h>
int main(){
return 0:
}
#包括
#包括
int main(){
返回0:
}
附加这些行是有效的。这是我的密码:
#! /bin/bash
for arg in "$@"
do
[ ${arg: -2} == ".c" ] && touch "$arg" || touch "$arg.c"
echo '#include <stdio.h>' > "$arg"
echo '#include <stdlib.h>' >> "$arg"
echo $'\nint main90{\n\n\t' >> "$arg"
echo $'\n\treturn 0;\n\n}' >> "$arg"
done
#/bin/bash
对于“$@”中的arg
做
[${arg:-2}=“.c”]&触摸“$arg”| |触摸“$arg.c”
echo“#include”>“$arg”
echo“#include”>>“$arg”
echo$'\nIT main90{\n\n\t'>>“$arg”
echo$'\n\t返回0;\n\n}'>>“$arg”
完成
如您所见,它可以创建的文件数量与touch
可以获取的参数数量相同。如果我忘了指定.c
扩展名,条件循环(do后面的一行)很有用:但问题是当参数不是以.c
结尾时,if
和else
都会执行,但如果我没有“忘记”指定它是一个c文件,则可以
我怎样才能解决这个问题呢?它不会同时占用两个分支。它会根据扩展名进行
触摸
,但如果您输入的是扩展名,则echo
序列会将其输出放在没有扩展名的文件中
我将重构为使用案例
,使用a打印多行,并完全跳过触摸
;但最简单的解决方法是,如果输出文件缺少扩展名,只需更改输出文件名
for arg in "$@"
do
case $arg in
*.c) ;;
*) arg="$arg.c";;
esac
cat <<'____HERE' > "$arg"
#include <stdio.h>
#include <stdlib.h>
int main(){
return 0;
}
____HERE
done
“$@中的参数的”
做
案例$arg in
*(c);;
*)arg=“$arg.c”;;
以撒
cat与此处文件的备选方案:
for arg in "$@"; do
if [ "${arg: -2}" == ".c" ]; then
filename="$arg"
else
filename="${arg}.c"
fi
cat<<EOT >"$filename"
#include <stdio.h>
#include <stdlib.h>
int main() {
return 0;
}
EOT
done
“$@”中arg的;做
如果[“${arg:-2}”==“.c”];然后
filename=“$arg”
其他的
filename=“${arg}.c”
fi
cat有一点变化:
#! /bin/bash
for arg in "$@"
do
[[ ${arg: -2} == ".c" ]] && FILE="$arg" || FILE="$arg.c"
echo '#include <stdio.h>' > "$FILE"
echo '#include <stdlib.h>' >> "$FILE"
echo $'\nint main90{\n\n\t' >> "$FILE"
echo $'\n\treturn 0;\n\n}' >> "$FILE"
done
#/bin/bash
对于“$@”中的arg
做
[[${arg:-2}=>.c”]&&FILE=“$arg”| | FILE=“$arg.c”
echo“#include”>“$FILE”
echo“#include”>>“$FILE”
echo$'\n在main90{\n\n\t'>>“$FILE”
echo$'\n\t返回0;\n\n}'>>“$FILE”
完成
简化的解决方案避免了对条件的任何需要。无论原始参数是否以.c
结尾,您都希望创建一个.c
文件,如果该文件不存在,则有效地添加它。这与总是将其添加到尝试删除它的结果中是一样的。您也不需要使用touch
显式创建文件;如果需要,输出重定向将创建文件
这还演示了将模板内容写入文件的另一种方法
for arg in "$@"
do
{
printf '#include <stdio.h>\n'
printf '#include <stdlib.h>\n'
printf '\nint main90 {\n'
printf '\n\treturn 0;\n\n}\n' # end with a newline
} > "${arg%.c}.c"
done
“$@中的参数的”
做
{
printf'#包括\n'
printf'#包括\n'
printf'\n在main90{\n'
printf'\n\t返回0;\n\n}\n'#以换行结束
}>“${arg%.c}.c”
完成
请注意,您的文件可能应该是一个正确的POSIX文本文件,以换行符结尾。如果$arg
不包含.c
,您将创建一个名为$arg.c
的文件。稍后在脚本中,您将写入$arg
,但我们刚刚确定$arg
不包含.c
,因此您将使用该重定向写入非.c
文件。但是,我怀疑当您的$arg
包含.c
时,此脚本工作正常。请注意条件&&cmd1 | | cmd2
并不完全等同于if条件then cmd1;else-cmd2;fi
–如果cmd1
失败,将执行cmd2
!(请参阅)您可以用一个bash
ism替换另一个更清晰的:if[[$arg==*.c]];然后触摸“$arg”;或者点击“$arg.c”
。您也可以完全省去测试,使用POSIX兼容的参数扩展:arg=${arg%.c}.c
。如果有此条.c
,则无论它是否在最初的位置,都会将其放回原处。您好,谢谢您的回答。你能解释一下这只猫的。。。等等,是什么意思?或者你能给我一个解释它的链接吗?可能是因为heredoc更容易阅读和书写(以及更改)。实际上我使用的是printf
,而不是heredoc,但有人认为他们可以“改进”我的答案。不管怎样,echo
都有一些令人讨厌的可移植性问题;无论是printf
还是cat
here文档都会优雅地避免这些内容。我最初发布的printf
答案使选项卡等变得清晰;但是一个在正确位置有标签的here文档也可以很好地工作(只是不能象征性地显示标签的位置),所以我将@JohnKugelman留下编辑。我最初的答案只有一个printf
,所以你也可以去掉大括号。(这比我以前盲目复制/粘贴OP的代码要优雅得多。)我曾玩弄过,但它会变得丑陋,除非你使用一个行数组,在这种情况下,你最好接受使用你使用的here文档运行cat
的成本。