Skip to content

shell语法

shell语法

image-20231023162325946

目录

[toc]

linux中如何把一段shell代码执行结果赋值给变量?

在 Linux 中,你可以使用命令替换(Command Substitution)将一段 shell 代码的执行结果赋值给变量。有两种主要的语法形式用于命令替换:

1、反引号(``)

使用反引号可以将命令的输出嵌套到变量中:

bash
result=`your_shell_command`

例如:

bash
bashcurrent_date=`date`echo"Today is $current_date"

2、$()语法

使用 $()语法也可以实现相同的效果,而且相对更加清晰:

bash
result=$(your_shell_command)

同样的例子:

bash
current_date=$(date)echo"Today is $current_date"

这两种语法都会执行 your_shell_command,并将其标准输出的结果赋值给 result变量。

注意事项:

  • 如果你在反引号或 $()中包含的 shell 命令包含空格或特殊字符最好将整个命令用双引号括起来,以防止意外的解释错误。
  • 在 Bash 中,$()更常用,而且在嵌套使用时更容易阅读。

例如:

bash
result="$(your_shell_command)"

这样可以确保在命令执行和输出赋值时处理空格等特殊情况更加稳妥。

linux打印变量的方式?

在 Linux 中,你可以使用 echoprintf命令来打印变量的值。以下是两种常用的方式:

  1. 使用 echo
bashvariable="Hello,Linux!"echo $variable

或者使用引号:

bashecho "$variable"

echo命令中,$variable会被替换为变量的实际值,并打印到标准输出。

  1. 使用 printf
bashvariable="Hello,Linux!"printf "%s\n"$variable

printf允许更复杂的格式化,但在简单的情况下,使用 echo更为常见。

这两种方法都会输出变量的值到终端。选择使用哪一种取决于你的需求,如果只是简单地打印变量的值,通常使用 echo就足够了。如果需要更复杂的格式化或更精确的控制,可以考虑使用 printf

linux里如何自定义变量

已解决。

2023年10月23日

  • gpt问答

2023年10月23日

在Linux中,可以使用export命令来自定义变量。具体步骤如下:

  1. 打开终端,进入Linux命令行界面。

  2. 输入以下命令来定义变量:

    export 变量名=变量值

    请将"变量名"替换为你想要定义的变量的名称,将"变量值"替换为你想要赋给变量的值。

  3. 如果你想要将变量定义为永久性的,可以将以上命令添加到你的.bashrc.bash_profile文件中。这样,在每次启动终端时,该变量都会自动加载。

例如,要定义一个名为MY_VAR的变量,并将其值设置为Hello World,可以执行以下命令:

export MY_VAR="Hello World"

之后,你就可以在终端中使用$MY_VAR来引用这个变量。例如,可以输入echo $MY_VAR来显示变量的值。

  • 自己测试过程

这里先用本地shell命令查看即可,后期再实现次功能

bash
exporthexoMdCounts=`ls  BaiduSyncdisk/source/_posts/ |wc -l`exportcounts="当前hexo md文档数量合计:echo ${hexoMdCounts} 个"echo${hexoMdCounts}echo${counts}exporthexoMdCounts=`ls  BaiduSyncdisk/source/_posts/ |wc -l`exportcounts="当前hexo md文档数量合计:echo ${hexoMdCounts} 个"echo${counts}

image-20231023155340577

shell方式实现过程:

image-20231023160242618

image-20231023160253727

image-20231023160309345

测试效果:

image-20231023160322192

image-20231023160338708

完美,符合预期。😘

shell语法安装软件

image-20230302224953644

bash
(set-x;cd"$(mktemp-d)"&&OS="$(uname|tr'[:upper:]''[:lower:]')"&&ARCH="$(uname-m|sed-e's/x86_64/amd64/'-e's/\(arm\)\(64\)\?.*/\1\2/'-e's/aarch64$/arm64/')"&&KREW="krew-${OS}_${ARCH}"&&curl-fsSLO"https:tarzxvf"${KREW}.tar.gz"&&./"${KREW}"installkrew)

for循环

案例:批量执行命令

bash
fori in{6..20};doecho10.130.194.$i ;ssh10.130.194.$i df-h;echo-e"\n";done

案例

bash
k=0fori in{a..l}doecho"i am ${i}"done或者:fori in{a..l};do"smartctl -a /dev/sd${i}"|grep-iSerial;done

案例:for循环的脚本如何赋值给一个变量?==(测试成功)==

gpt

for循环的脚本如何赋值给一个变量?

如果你想将包含for循环的脚本赋值给一个变量,你可以使用反引号(``)或$()来执行命令并将其输出赋给变量。这是一个示例:

bash
fori in{1..5}doecho"Iteration $i"done# 将脚本赋值给变量script=$(cat<<'END_SCRIPT'for i in {1..5}doecho "Iteration $i"doneEND_SCRIPT)# 执行脚本eval"$script"

在这个例子中,使用cat <<'END_SCRIPT'来创建一个包含多行脚本的文本块。<<表示Here文档,'END_SCRIPT'中的单引号使其中的内容被视为纯文本,不进行变量扩展。

然后,使用$(command)或反引号`` 来执行这个命令并将输出赋给变量 script

最后,你可以使用eval来执行存储在变量中的脚本。请注意,eval可能有一些潜在的安全性问题,因此在使用时要小心。

注意:使用eval来执行脚本是为了将脚本中的变量展开和执行,但这样也可能引入安全问题。确保你的脚本不包含不受信任的输入,以防止潜在的安全风险。


测试过程:

bash
[root@hexo-blog rsync-wiki]# eval "$script"^C[root@hexo-blog rsync-wiki]# fori in{1..5}>do>echo "Iteration $i">doneIteration1Iteration2Iteration3Iteration4Iteration5[root@hexo-blog rsync-wiki]# [root@hexo-blog rsync-wiki]# # 将脚本赋值给变量[root@hexo-blog rsync-wiki]# script=$(cat<<'END_SCRIPT'>for i in {1..5}>do>echo "Iteration $i">done>END_SCRIPT>)[root@hexo-blog rsync-wiki]# [root@hexo-blog rsync-wiki]# # 执行脚本[root@hexo-blog rsync-wiki]# eval "$script"Iteration 1Iteration 2Iteration 3Iteration 4Iteration 5[root@hexo-blog rsync-wiki]#

while循环

死循环

bash
whiletrue;doecholove;done

案例:如何加一个换行符==(测试成功)==

如何给输出的内容末尾加上一个换行符呢?

  • 案例

如果你想要给输出的内容末尾加上一个换行符,你可以使用 echo命令,并在输出中添加 -e选项。以下是一个示例:

bash
[root@hexo-blog linux-test]# echo -e "你的输出内容\n"你的输出内容[root@hexo-blog linux-test]#

这个命令中的 -e选项表示对转义字符进行解释,而 \n表示换行符。你可以将 "你的输出内容"替换为实际的输出内容。

  • 案例

如果是在脚本或命令中,你可以在最后一行的输出中使用 echo -e来确保在末尾添加一个换行符。例如:

[root@hexo-blog linux-test]# ls;echo -edemo.txt[root@hexo-blog linux-test]#

这样可以确保 your_command的输出末尾有一个换行符。

案例:shell报错问题(==已解决==)

$ ssh root@47.97.48.237cd /root/rsync/site &&systemctl reload nginx 这个命令好像有语法错误,请帮我改正下

对于您提供的命令,ssh指令需要将整个远程执行命令部分放在引号里以确保正确执行,尤其是包含了多个命令的情况。请尝试以下形式的命令:

ssh root@47.97.48.237 'cd /root/rsync/site &&systemctl reload nginx'

通过将cd /root/rsync/site &&systemctl reload nginx部分放在引号中,命令将以整个字符串作为远程执行的命令。这将使您能够先进入指定目录,然后执行systemctl reload nginx命令,而不会遇到语法错误。

6啊😂

image-20230916074007102

案例:配置环境变量以及初始化某个软件的脚本

bash
exportNVM_DIR="$([-z"${XDG_CONFIG_HOME-}"] &&printf%s "${HOME}/.nvm"||printf%s "${XDG_CONFIG_HOME}/nvm")"[-s"$NVM_DIR/nvm.sh"] &&\."$NVM_DIR/nvm.sh"这段代码是什么意思?

这段代码是用于配置环境变量以及初始化 NVM(Node Version Manager)的脚本,让你在任何新的终端会话中都能使用 NVM。具体来说,它做了以下几件事:

  1. export NVM_DIR="$([-z "${XDG_CONFIG_HOME-}"] &&printf %s "${HOME}/.nvm"||printf %s "${XDG_CONFIG_HOME}/nvm")":这行代码设定了一个名为 NVM_DIR的环境变量,它指向 NVM 的安装目录。这里用到了一个条件表达式,检查环境变量 XDG_CONFIG_HOME是否已设置。如果没有设置(-z "${XDG_CONFIG_HOME-}"为真),就使用默认的 ${HOME}/.nvm作为 NVM 的安装目录;如果设置了 XDG_CONFIG_HOME,则使用 ${XDG_CONFIG_HOME}/nvm作为安装目录。printf %s是用来确保路径被正确地输出而不解释任何特殊字符。

  2. [-s "$NVM_DIR/nvm.sh"] &&\. "$NVM_DIR/nvm.sh":这行代码首先检查 nvm.sh脚本是否存在于上一行指定的 NVM_DIR目录中,并且文件大小不为零(表示文件确实存在且不为空)。如果这个条件为真(即文件存在且不为空),则执行(source)该脚本。.(或者等价的source命令)用于在当前的 shell 环境中执行 nvm.sh脚本,这样就可以在任何新的终端会话中使用 NVM 相关的命令了。

简而言之,这段代码确保了每次你打开一个新的终端会话时,NVM 都会被正确初始化,使得你可以使用 NVM 管理 Node.js 版本。


自己测试:

bash
exportNVM_DIR="$([-z"${XDG_CONFIG_HOME-}"] &&printf%s "${HOME}/.nvm"||printf%s "${XDG_CONFIG_HOME}/nvm")"[-s"$NVM_DIR/nvm.sh"] &&\."$NVM_DIR/nvm.sh"#存在XDG_CONFIG_HOME="/tmp"/tmp/nvm/nvm.sh#nvm.sh#!/bin/bashecho"i love you ,xyy---tmp"#不存在XDG_CONFIG_HOME=/root/.nvm/nvm.sh#nvm.sh#!/bin/bashecho"i love you ,xyy---root"

image-20240324145055693

测试符合预期。

案例:检查是否为交互式 shell

image-20240728154128846

检查是否为交互式 shell

bash
# 检查是否为交互式 shellif[[$-!=*i*]];thenreturnfi
  • 这段代码检查当前shell是否为交互式shell。如果不是交互式shell,脚本会直接返回,避免在非交互式shell环境中执行,从而不会干扰其他服务的正常运行。

详细解释:

这段代码用于检查当前的 shell 是否为交互式 shell。以下是对这段代码的详细解释:

bash
# 检查是否为交互式 shellif[[$-!=*i*]];thenreturnfi
  1. $-变量

    • $-是一个特殊的 shell 变量,它包含了当前 shell 的选项标志。这些选项标志是在启动 shell 时设置的,或者是在 shell 运行过程中通过 set命令设置的。
    • 例如,$-可能包含的选项有 i(交互式)、v(详细模式)、x(追踪模式)等。
  2. [[... ]]条件测试

    • [[... ]]是 Bash 中的一个条件测试结构,用于执行条件判断。
    • $- !=*i*是一个字符串匹配表达式,用于检查 $-变量中是否包含字符 i
  3. *i*模式

    • *i*是一个通配符模式,其中 *表示任意字符(包括零个字符),i是要匹配的字符。
    • 因此,$- !=*i*的意思是:如果 $-变量中不包含字符 i,则条件为真。
  4. if ... then ... fi结构

    • 如果条件为真(即 $-变量中不包含字符 i),则执行 then块中的代码。
    • 在这个例子中,then块中的代码是 return表示从当前函数或脚本中返回,不再执行后续的代码。
  5. return命令

    • return命令用于从当前函数或脚本中退出。如果在一个脚本中使用 return,它会立即停止脚本的执行。

总结

这段代码的目的是确保脚本只在交互式 shell 中运行。如果当前 shell 不是交互式 shell(即 $-变量中不包含字符 i),脚本会立即返回,不再执行后续的代码。这样可以避免脚本在非交互式环境中(例如在后台任务或某些自动化脚本中)产生不必要的输出或干扰其他进程。

案例:如何远程执行一个shell脚本?-2024.8.17(已解决)

需求

bash
curl-Ohttp:这条命令是从远程服务器下载ruyu-blog-install-v4.sh脚本并执行的,是用来部署一个博客的。我想实现一个需求:在执行这条命令后,默认是所有日志都打印在当前终端上,能不能实现如下需求?1.默认是所有日志都打印在当前终端上2.同时,把所有日志保存在/root/ruyuy-blog-all.log,把所有报错日志保存在/root/ruyuy-blog-error.logcurl-Ohttp:curl-Ohttp:# 执行脚本并记录日志sh-xruyu-blog-install-v4.sh>>(tee/root/ruyuy-blog-all.log)2>>(tee/root/ruyuy-blog-error.log >&2)

这里使用了 tee命令来实现日志的双重输出:

  • >>(tee /root/ruyuy-blog-all.log)将标准输出(stdout)同时输出到终端和 /root/ruyuy-blog-all.log文件。
  • 2>>(tee /root/ruyuy-blog-error.log >&2)将标准错误输出(stderr)同时输出到终端和 /root/ruyuy-blog-error.log文件。

解释

  • curl -O http:curl-Ohttp:###输入自己当前服务器的ip,然后坐等部署成功,整个时间预计在12min左右。

效果

image-20240818091616530