1、shell语法
更新于:2024年3月21日
shell语法
目录
[toc]
linux中如何把一段shell代码执行结果赋值给变量?
在 Linux 中,你可以使用命令替换(Command Substitution)将一段 shell 代码的执行结果赋值给变量。有两种主要的语法形式用于命令替换:
1、反引号(``)
使用反引号可以将命令的输出嵌套到变量中:
result=`your_shell_command`
例如:
bashcurrent_date=`date`
echo "Today is $current_date"
2、$()
语法
使用 $()
语法也可以实现相同的效果,而且相对更加清晰:
result=$(your_shell_command)
同样的例子:
current_date=$(date)
echo "Today is $current_date"
这两种语法都会执行 your_shell_command
,并将其标准输出的结果赋值给 result
变量。
注意事项:
- 如果你在反引号或
$()
中包含的 shell 命令包含空格或特殊字符,最好将整个命令用双引号括起来,以防止意外的解释错误。 - 在 Bash 中,
$()
更常用,而且在嵌套使用时更容易阅读。
例如 :
result="$(your_shell_command)"
这样可以确保在命令执行和输出赋值时处理空格等特殊情况更加稳妥。
linux打印变量的方式?
在 Linux 中,你可以使用 echo
或 printf
命令来打印变量的值。以下是两种常用的方式:
- 使用
echo
bashvariable="Hello, Linux!"
echo $variable
或者使用引号:
bashecho "$variable"
在 echo
命令中,$variable
会被替换为变量的实际值,并打印到标准输出。
- 使用
printf
bashvariable="Hello, Linux!"
printf "%s\n" $variable
printf
允许更复杂的格式化,但在简单的情况下,使用 echo
更为常见。
这两种方法都会输出变量的值到终端。选择使用哪一种取决于你的需求,如果只是简单地打印变量的值,通常使用 echo
就足够了。如果需要更复杂的格式化或更精确的控制,可以考虑使用 printf
。
linux里如何自定义变量
已解决。
2023年10月23日
- gpt问答
2023年10月23日
在Linux中,可以使用export
命令来自定义变量。具体步骤如下:
-
打开终端,进入Linux命令行界面。
-
输入以下命令来定义变量:
export 变量名=变量值
请将"变量名"替换为你想要定义的变量的名称,将"变量值"替换为你想要赋给变量的值。
-
如果你想要将变量定义为永久性的,可以将以上命令添加到你的
.bashrc
或.bash_profile
文件中。这样,在每次启动终端时,该变量都会自动加载。
例如,要定义一个名为MY_VAR
的变量,并将其值设置为Hello World
,可以执行以下命令:
export MY_VAR="Hello World"
之后,你就可以在终端中使用$MY_VAR
来引用这个变量。例如,可以输入echo $MY_VAR
来显示变量的值。
- 自己测试过程
这里先用本地shell命令查看即可,后期再实现次功能
export hexoMdCounts=`ls BaiduSyncdisk/source/_posts/ |wc -l`
export counts="当前hexo md文档数量合计: echo ${hexoMdCounts} 个"
echo ${hexoMdCounts}
echo ${counts}
!
export hexoMdCounts=`ls BaiduSyncdisk/source/_posts/ |wc -l`
export counts="当前hexo md文档数量合计: echo ${hexoMdCounts} 个"
echo ${counts}
shell方式实现过程:
测试效果:
完美,符合预期。😘
shell语法安装软件
(
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://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
tar zxvf "${KREW}.tar.gz" &&
./"${KREW}" install krew
)
for循环
案例:批量执行命令
for i in {6..20}; do echo 10.130.194.$i ; ssh 10.130.194.$i df -h; echo -e "\n"; done
案例
k=0
for i in {a..l}
do
echo "i am ${i}"
done
或者:
for i in {a..l};do "smartctl -a /dev/sd${i}" |grep -i Serial; done
案例:for循环的脚本如何赋值给一个变量?==(测试成功)==
gpt
for循环的脚本如何赋值给一个变量?
如果你想将包含for循环的脚本赋值给一个变量,你可以使用反引号(``)或$()来执行命令并将其输出赋给变量。这是一个示例:
for i in {1..5}
do
echo "Iteration $i"
done
# 将脚本赋值给变量
script=$(cat <<'END_SCRIPT'
for i in {1..5}
do
echo "Iteration $i"
done
END_SCRIPT
)
# 执行脚本
eval "$script"
在这个例子中,使用cat <<'END_SCRIPT'
来创建一个包含多行脚本的文本块。<<
表示Here文档,'END_SCRIPT'
中的单引号使其中的内容被视为纯文本,不进行变量扩展。
然后,使用$(command)
或反引号`` 来执行这个命令并将输出赋给变量 script
。
最后,你可以使用eval
来执行存储在变量中的脚本。请注意,eval
可能有一些潜在的安全性问题,因此在使用时要小心。
注意:使用eval
来执行脚本是为了将脚本中的变量展开和执行,但这样也可能引入安全问题。确保你的脚本不包含不受信任的输入,以防止潜在的安全风险。
测试过程:
[root@hexo-blog rsync-wiki]# eval "$script"^C
[root@hexo-blog rsync-wiki]# for i in {1..5}
> do
> echo "Iteration $i"
> done
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5
[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 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5
[root@hexo-blog rsync-wiki]#
while循环
死循环
while true; do echo love; done
案例:如何加一个换行符==(测试成功)==
如何给输出的内容末尾加上一个换行符呢?
- 案例
如果你想要给输出的内容末尾加上一个换行符,你可以使用 echo
命令,并在输出中添加 -e
选项。以下是一个示例:
[root@hexo-blog linux-test]# echo -e "你的输出内容\n"
你的输出内容
[root@hexo-blog linux-test]#
这个命令中的 -e
选项表示对转义字符进行解释,而 \n
表示换行符。你可以将 "你的输出内容" 替换为实际的输出内容。
- 案例
如果是在脚本或命令中,你可以在最后一行的输出中使用 echo -e
来确保在末尾添加一个换行符。例如:
[root@hexo-blog linux-test]# ls;echo -e
demo.txt
[root@hexo-blog linux-test]#
这样可以确保 your_command
的输出末尾有一个换行符。
案例:shell报错问题(==已解决==)
$ ssh root@47.97.48.237 cd /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啊😂
案例:配置环境变量以及初始化某个软件的脚本
export NVM_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。具体来说,它做了以下几件事:
-
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
是用来确保路径被正确地输出而不解释任何特殊字符。 -
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
:这行代码首先检查nvm.sh
脚本是否存在于上一行指定的NVM_DIR
目录中,并且文件大小不为零(表示文件确实存在且不为空)。如果这个条件为真(即文件存在且不为空),则执行(source)该脚本。.
(或者等价的source
命令)用于在当前的 shell 环境中执行nvm.sh
脚本,这样就可以在任何新的终端会话中使用 NVM 相关的命令了。
简而言之,这段代码确保了每次你打开一个新的终端会话时,NVM 都会被正确初始化,使得你可以使用 NVM 管理 Node.js 版本。
自己测试:
export NVM_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/bash
echo "i love you ,xyy---tmp"
#不存在
XDG_CONFIG_HOME=
/root/.nvm/nvm.sh
#nvm.sh
#!/bin/bash
echo "i love you ,xyy---root"
测试符合预期。
案例:检查是否为交互式 shell
检查是否为交互式 shell
# 检查是否为交互式 shell
if [[ $- != *i* ]]; then
return
fi
- 这段代码检查当前shell是否为交互式shell。如果不是交互式shell,脚本会直接返回,避免在非交互式shell环境中执行,从而不会干扰其他服务的正常运行。
详细解释:
这段代码用于检查当前的 shell 是否为交互式 shell。以下是对这段代码的详细解释:
# 检查是否为交互式 shell
if [[ $- != *i* ]]; then
return
fi
-
$-
变量:$-
是一个特殊的 shell 变量,它包含了当前 shell 的选项标志。这些选项标志是在启动 shell 时设置的,或者是在 shell 运行过程中通过set
命令设置的。- 例如,
$-
可能包含的选项有i
(交互式)、v
(详细模式)、x
(追踪模式)等。
-
[[ ... ]]
条件测试:[[ ... ]]
是 Bash 中的一个条件测试结构,用于执行条件判断。$- != *i*
是一个字符串匹配表达式,用于检查$-
变量中是否包含字符i
。
-
*i*
模式:*i*
是一个通配符模式,其中*
表示任意字符(包括零个字符),i
是要匹配的字符。- 因此,
$- != *i*
的意思是:如果$-
变量中不包含字符i
,则条件为真。
-
if ... then ... fi
结构:- 如果条件为真(即
$-
变量中不包含字符i
),则执行then
块中的代码。 - 在这个例子中,
then
块中的代码是return
,表示从当前函数或脚本中返回,不再执行后续的代码。
- 如果条件为真(即
-
return
命令:return
命令用于从当前函数或脚本中退出。如果在一个脚本中使用return
,它会立即停止脚本的执行。
总结
这段代码的目的是确保脚本只在交互式 shell 中运行。如果当前 shell 不是交互式 shell(即 $-
变量中不包含字符 i
),脚本会立即返回,不再执行后续的代码。这样可以避免脚本在非交互式环境中(例如在后台任务或某些自动化脚本中)产生不必要的输出或干扰其他进程。
案例:如何远程执行一个shell脚本?-2024.8.17(已解决)
需求
curl -O http://47.100.215.163:6080/public/code/ruyu-blog-install-v4.sh && sh -x ruyu-blog-install-v4.sh
这条命令是从远程服务器下载ruyu-blog-install-v4.sh脚本并执行的,是用来部署一个博客的。
我想实现一个需求:
在执行这条命令后,默认是所有日志都打印在当前终端上,能不能实现如下需求?
1.默认是所有日志都打印在当前终端上
2.同时,把所有日志保存在/root/ruyuy-blog-all.log,把所有报错日志保存在/root/ruyuy-blog-error.log
curl -O http://47.100.215.163:6080/public/code/ruyu-blog-install-v4.sh ; sh -x ruyu-blog-install-v4.sh > >(tee /root/ruyuy-blog-all.log) 2> >(tee /root/ruyuy-blog-error.log >&2)