公开学习文档

公开学习文档


shell

<h2>原理</h2> <p>shell 脚本中调用命令时:</p> <ul> <li> <p>如果是直接调用,则是直接起子进程</p> </li> <li>如果要获取命令的输出结果,则是起 pipe 和子进程,通过 pipe 获取子进程的输出</li> </ul> <h2>注意</h2> <p>文件锁注意在起子进程时会继续被占用</p> <h2>$ 用法</h2> <pre><code class="language-sh">$# # 参数个数,不包括 $0 $@ # 获取所有参数列表,不包括 $0。 # 不加括号时,单纯按照空格来分割元素; # 加括号时则是按照实际的参数来处理。所以脚本马甲要用 &amp;quot;$@&amp;quot; 传递参数,注意有引号。(不加引号有什么影响?答:当参数中有 &amp;quot;aaa bbb&amp;quot; 这种就会有问题) $* # 不加引号时,和 $@ 一样,效果都是数组; # 加引号时,&amp;quot;$*&amp;quot; 把所有参数合并成一个字符串;而 &amp;quot;$@&amp;quot; 是字符串数组。 $$ # 当前进程 ID $! # 后台运行的最后一个进程的 ID 号 $PPID # 父进程</code></pre> <p>测试如下(传入参数只有 4 个,如果不加引号,会被当成 5 个参数):</p> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=9d1460792829e5044c0cb35090340ae1&amp;amp;file=file.png" alt="" /></p> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=eeb9ca3da08ce4693486c655d3c0219f&amp;amp;file=file.png" alt="" /></p> <p>注意:如果传入的参数多于 9 个,则不能使用 $10 来引用第 10 个参数,而是要用 ${10} 来引用。</p> <h2>基础</h2> <p>1、rm -f 不会判断文件是否存在,因为不存在也不会报错</p> <p>2、临时文件直接 mv -f 到正式文件,避免磁盘不足等问题</p> <p>3、开头为 #!/bin/bash</p> <p>4、命令中的变量加引号,防止注意,如 <code>ls &amp;quot;$foo&amp;quot;</code>。需要注意:这种情况下,如果路径中含有 * 号,则不生效</p> <h2>脚本做马甲</h2> <p>脚本马甲要用 &quot;$@&quot; 传递参数,注意有引号</p> <h2>for</h2> <pre><code class="language-shell">#!/bin/bash max_count=5 for ((i=max_count; i&amp;gt;0; i--)); do echo $i done</code></pre> <h2>split string</h2> <pre><code class="language-shell">#!/usr/bin/env bash IN=&amp;quot;bla@some.com;john@home.com&amp;quot; mails=$(echo $IN | tr &amp;quot;;&amp;quot; &amp;quot;\n&amp;quot;) for addr in $mails do echo &amp;quot;&amp;gt; [$addr]&amp;quot; done</code></pre> <h2>awk 命令</h2> <p>使用示例:</p> <pre><code class="language-shell"># 匹配 /bin/sh 和 /bin/bash 行 PSLIST=`ps aux --cols=1000 | awk '/\/bin\/(ba)?sh/{print $11&amp;quot; &amp;quot;$12&amp;quot; &amp;quot;$13}'`</code></pre> <ul> <li> <p>getline 带参数和不带参数,效果是不一样的:</p> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=535c984bb1d2ba6813e4143379b6f141" alt="" /></p> <p>总结:getline 是获取下一行内容。当带变量时,不改变内部环境变量;不带变量就会改变变量</p> </li> <li> <p>变量截取:</p> <p><a href="https://www.runoob.com/linux/linux-shell-variable.html">https://www.runoob.com/linux/linux-shell-variable.html</a></p> </li> <li> <p>参考文档</p> <p><a href="https://www.bookstack.cn/read/junmajinlong-awk/0e1306c3b34de2ec.md">https://www.bookstack.cn/read/junmajinlong-awk/0e1306c3b34de2ec.md</a></p> </li> </ul> <h2>shell 判断</h2> <p>-z 判断变量时:</p> <ul> <li> <p>如果关注空内容(即都是空格),则变量要带引号</p> </li> <li>如果不关注内容,则变量不要加引号</li> </ul> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=e52e905e9ba97bfa353829f91773e0ec&amp;amp;file=file.png" alt="" /></p> <p>-n 判断变量时(建议用 ! -z 替换):</p> <ul> <li>变量必须加引号,否则会有问题。但空内容(即都是空格)会被认为“有内容”</li> </ul> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=58d9c31087c8b8b5852488ab0314a31f&amp;amp;file=file.png" alt="" /></p> <h2>获取脚本自身的目录</h2> <p>获取执行脚本全路径:</p> <p><code>readlink -e $0</code></p> <p>获取目录:</p> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=81f27fb2e5ed3bac93d4e36759cbfc74&amp;amp;file=file.png" alt="" /></p> <p>&gt; 参考资料:<a href="https://blog.csdn.net/10km/article/details/51906821">https://blog.csdn.net/10km/article/details/51906821</a></p> <h2>调用命令</h2> <pre><code class="language-shell"># 如果是这样调用命令,则是通过管道 pipe([3, 4]) 来获取输出,获取完成后就会关掉句柄。而且是每次这样调用,都重新创建 a=`ls /tmp` # 如果是直接调用命令,则是直接直接输出,没用管道 ls /tmp</code></pre> <h2>shell 中关闭句柄</h2> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=cf25ed156c0dab09accbc5b0dbfab2e9&amp;amp;file=file.png" alt="" /></p> <p>&gt; 参考文档:<a href="https://blog.csdn.net/vanloswang/article/details/40862081">https://blog.csdn.net/vanloswang/article/details/40862081</a></p> <h2>获取某个分区占用情况</h2> <pre><code class="language-shell">df -hm /var</code></pre> <h2>去掉 %</h2> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=60d990d22e63a68dd34888c52bb4b173&amp;amp;file=file.png" alt="" /></p> <h2>变量截取</h2> <p>&gt; <a href="https://blog.csdn.net/jined/article/details/124196546">https://blog.csdn.net/jined/article/details/124196546</a></p> <h2>kill</h2> <pre><code class="language-sh">kill -15 0 # 进程号为 0 则将信号发给当前进程组,包括自已。(当脚本有后台运行的任务时,可以用此方法杀掉。shell 脚本的子进程属于同一个进程组;但 ssh 窗口起的子进程,却不是同一个进程组) kill -15 -1 # 进程号为 -1,则杀掉所有能杀掉的进程 kill -15 -n # 进程号小于 -1,则将信息发给进程组 n kill -0 {id} # 不发信号,只是检查 进程号或进程组号 是否存在/权限。备注:比较 ps 高效;但测试似乎不能测试进程组号</code></pre> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=ae009a20009fb474909d38a0a7276193&amp;amp;file=file.png" alt="" /></p>

页面列表

ITEM_HTML