-
2021-05-11 08:36:27
在shell 脚本中执行命令,是以“阻塞”方式执行的,这点类似于 system 系统调用,之前并没有意识到这一点,为此,犯错了。
这是一个监控脚本,功能是检查一个程序(以下记做:daemonp)是否在运行(按“程序名”检测),如果不在,则启动它。代码也很简单,在一个死循环中,grep ps 的结果,如果结果为空,则启动daemonp。脚本是别人写的,循环中有sleep 1命令(其实这个sleep没用)。我臆断为每1s检查一次。事实是:脚本检查到daemonp没有运行,则启动它,这时脚本阻塞在 daemonp 的运行上,直到 daemonp 运行结束(挂掉也算)。如果 daemonp 挂了,则脚本继续执行,然后再次检查到daemonp 不存在,启动,阻塞,······,周而复始。
这个脚本运行很好,但是如果用它监控多个程序,就有问题了(假设还监控daemonq)。假设daemonp 和 daemonq 都没有运行,并假设先检测到 daemonp 没有运行,然后启动,现在脚本阻塞到 daemonp 的调用上,没有可能启动 daemonq 了。
解决办法是把 daemonp 和 daemonq 放到后台运行,没有阻塞了,这时 sleep 1 才有用。脚本每1s检查一次。
把命令放到后台的方式是命令后加“&”,但是如果把命令放到变量中(假设为CMD),用``执行,放到后台的方式是`$CMD` &
分享到:
0
更多相关内容 -
Java代码执行Linux脚本
2021-04-08 14:20:15Java代码执行Linux脚本1. 代码示例 java.io.IOException: Cannot run program "./home/jack/copyReport.sh": error=2, No such file or directory 1. 代码示例 /** * @author Jack魏 * @date 2021-04-08 */ ...Java代码执行Linux脚本
java.io.IOException: Cannot run program "./home/jack/copyReport.sh": error=2, No such file or directory
1. 代码示例
/** * @author Jack魏 * @date 2021-04-08 */ public class TestRun { public static void main(String[] args) { copyRepot(); } private static boolean IS_LINUX = false; static { IS_LINUX = System.getProperty("os.name").toLowerCase().contains("linux"); } /** * 执行拷贝脚本 */ private static void copyRepot() { try { String cmd = "source /home/jack/copyReport.sh"; if (IS_LINUX){ String[] cmdArr = {"/bin/sh", "-c", cmd}; if (IS_LINUX){ Process proc = Runtime.getRuntime().exec(cmdArr); proc.waitFor(); //阻塞,直到上述命令执行完 } } } catch (Exception e) { e.printStackTrace(); } } }
-
Linux中脚本的使用方法
2021-05-15 11:45:17Linux中脚本的使用方法一、前言关于Linux中的脚本的用法,一直没有时间去好好地总结,正好今天下雨,就好好的整理一下思路吧,其实精通了一门语言,比如C语言,学习其他语言需要的成本是非常少的,同样的脚本作为一...Linux中脚本的使用方法
一、前言
关于Linux中的脚本的用法,一直没有时间去好好地总结,正好今天下雨,就好好的整理一下思路吧,其实精通了一门语言,比如C语言,学习其他语言需要的成本是非常少的,同样的脚本作为一种比较简易的语言,只要知道了语法,我们在通过几个例子好好的理解和掌握一下常规的使用,这样就等于是入门了,之后要想精深的话,其实更应该学习一下Linux中的命令,比如三剑客、文件操作的命令、进程管理的命令、重定向、管道等,这样我们也算是能够登堂入室了,不管是什么语言,最重要的是使用,不用来使用的语言,学习是毫无意义的,过不了多长时间就会忘记的。
二、Linux脚本的使用
2.1、脚本的运行
脚本可以很简单,其实就是将Linux中的命令配上一定的语法去展现出来,下面我们看一个最简单的脚本,因为笔者是在windows中操作的,安装的Git里面就自带有Linux脚本的运行环境(MinGW64),其实和Linux里面是一样的,所以大家注意区分即可。
name='zyr'echo'hello,zyr'
(1)bash/sh 脚本名.sh
其中sh是bash这个程序的软连接,需要找到bash再执行,因此执行的要稍微慢一点,当脚本文件本身没有可执行权限时常使用的方法,使用ll命令可以看到文件权限属性x位为-号;或者脚本文件开头没有指定解释器时需要使用的方法,将重新启动一个子shell(进程)来执行命令。从运行也可以看出来,这个$name根本就不是我们设置的,只是这个系统中已经设置的,说明是重新启动了一个shell(子进程)来完成的,shell脚本执行完后子shell环境随即关闭,然后又回到父shell中。这样也好理解,因为如果凡事都需要shell自身来完成的话,有可能就阻塞了后续的执行了,这是一种折中的方法。
(2)path/脚本名.sh
如果是在当前文件夹下,需要使用 ./脚本名.sh 。使用这种方式需要脚本有执行权限,具体方法为:chmod a+x script-name。然后通过执行脚本绝对路径或者相对路径就可以执行脚本了。在生产环境中,运维人员由于忘记为该脚本设置可执行权限,然后直接使用,导致出错,将重新启动一个子shell(进程)来执行命令。因此,推荐第一种 bash script-name。出乎意料的,我们在没有执行权限的时候竟然运行成功了,这说明了什么,只能说明我们使用的这个MinGw64权限太大了。在Linux环境中就需要修改权限了。同样的也是重新启动了一个子进程。
(3)source script-name或者 . script-name
source或者“.”命令的功能是:读入脚本并执行脚本,即在当前Shell中执行source或“.”加载并执行的相关脚本文件的命令及语句,而不是产生一个子Shell来执行文件中的命令。可以看到我们使用这种命令实现了在本shell中执行该脚本的功能,正确的输出了name。
2.2、脚本规范的写法
在上面我们使用的脚本是不规范的,因为我们没有在开头描写我们要使用什么解释器来解释和执行,因此在正规的场景之中,我们需要写上这些信息,并且使用第一种方式来执行。一个规范的Shell脚本在第一行会指出由哪个程序(解释器)来执行脚本中的内容,这一行内容在Linux bash的编程一般为:#!/bin/bash或#!/bin/sh 。
(1)在Shell中如果一行的第一个字母是#,则是注释,但是写在第一行,则不是脚本注释行,如果写在某个命令之后,则变成注释行。
(2)sh为bash的软链接,大多数情况下,脚本的开头使用“#!/bin/bash”和“#!/bin/sh”是没有区别的,但更规范的写法是在脚本的开头使用“#!/bin/bash”。
#!/bin/bash
name='zyr'#定义变量
echo'hello,zyr' #输出字符串
2.3、脚本的语法
注意事项:
A1、当变量名被其他字符串混淆的时候,需要加{}
A2、对变量赋值的时候,在赋值号‘=’的左右不要留下空格
A3、在使用echo输出的时候,需要使用双引号""才能够将变量转换成数值输出出去,不然将会按照字符串处理。单引号更严格一些,可以防止任何变量扩展。双引号可以防止通配符扩展但允许变量扩展。
2.3.1、分支(判断)语句的用法
比如我们下面接收用户输入的参数,然后将这些参数显示出来并且对系统变量进行判断的脚本:
1 #!/bin/sh
2
3
4 #提示“请输入姓名”并等待30秒,把用户的输入保存入变量name中5 read -t 30 -p "请输入用户名称:"name6 #echo -e 处理特殊字符,如换行7 echo -e "\n"
8 echo "用户名为:$name"
9 #提示“请输入密码”并等待30秒,把用户的输入保存入变量age中,输入内容隐藏10 read -t 30 -s -p "请输入用户密码:"pw11 echo -e "\n"
12 echo "用户密码为:$pw"
13 #提示“请输入性别”并等待30秒,把用户的输入保存入变量sex中,只接受一个字符输入14 read -t 30 -n 1 -p "请输入用户性别:"sex15 echo -e "\n"
16 echo "性别为$sex"
17
18
19 #注意if的空格以及[]里面的空格20 if [ "$SHELL" = "/bin/bash" ];then
21 echo "SHELL is : $SHELL"
22 else
23 echo "login shell is $SHELL"
24 fi
可以看到根据脚本的不同命令,shell能够正确的执行并且显示相应的结果,同样的,这里要说一下if语句,在编写shell的时候,如果是在windows里面,我们最好使用sublime来编辑,这样可以很容易的发现出现的错误,比如说if语句,如果不注意空格,那么将会出错,在sublime中是能够看到提示的,如果是在Linux之中,我们就使用vim或者gedit这些都能智能提示的。
比如说下面的就是错误的,必须有空格才能识别完整,好的编辑器能够事半功倍:
当然if语句也有其他的写法,比如使用&&和||来表示的,根据我们的需要,再一点点的掌握。
2.3.2、循环语句的用法
接下来我们看一下while循环:
1 #!/bin/bash2
3 fileName=zyr.secret4 count=`cat $fileName | wc -l`5 #下面是一个管道,下面循环读文件中的每一行6 cat $fileName |
7 whileread line8 do
9 user=`echo $line|awk -F ':' '{print $1}'`10 #代表以 :分段$1就是取第1段11 uid=`echo $line|awk -F ':' '{print $3}'`12 echo "hello, $user Your UID is $uid"
13 done
14 echo "====User_count:$count===="
15 #前面求得的用户数
zyr:12:pw23
lsx:34:pw123
default:134:pw223
当然也可以使用for语句,比如下面的语句是创建文件夹,并且在文件夹里循环创建文件。
#!/bin/shcd/d/LinuxScriptmkdirshell_make
cd shell_makefor ((i=0; i<20; i++)); do
touchtest_zyr_$i.txtdone
掌握了顺序、分支、循环语句,在任何一个语言之中,我们都能够游刃有余了,这是因为程序最基本的三个元素就是这些语句了,只要我们多加熟悉,掌握其中的精妙之处,注意标点符号、空格、特殊字符的用法,再加上Linux中的一些基本的命令,我们就能很好的使用脚本来完成我们想要做的工作了。
2.4、Linux之中命令的一些基本技巧
使用curl抓取网页:
curl www.baidu.com
抓取并保存文件:
curl -o zyr.baidu www.baidu.com
#!/bin/bash
response=$(curl www.baidu.com)echo $response
三、总结
其实Linux脚本很容易学习,最重要的是多练习,并且有参考资料,可以及时去查阅,总体来说,使用Linux脚本的前提就是要掌握好Linux的命令,特别是那些常用的命令,之后将自己任务中常用的操作设计成脚本,然后使用起来就很方便了。当然还有很多东西都没有讲到,比如case语句,一些基本的符号表示的含义等等,但是这些在使用的时候还是很常用的,我们需要经常练习才行。
-
Linux中使用Shell脚本查看Java线程的CPU使用情况
2020-09-04 10:35:00主要介绍了Linux中使用Shell脚本查看Java线程的CPU使用情况,需要的朋友可以参考下 -
Java程序调用linux脚本-简单版
2021-02-02 15:44:02最近快要过年了,在研究Java程序直接调用linux脚本,保障系统故障时自动重启,虽然简单,但还是要记录一下,以免踩坑。如有不足,可以指出修正。 1、编写shell脚本 在服务器指定目录编写好本次要执行的shell脚本,...最近快要过年了,在研究Java程序直接调用linux脚本,保障系统故障时自动重启,虽然简单,但还是要记录一下,以免踩坑。
1、编写shell脚本
在服务器指定目录编写好本次要执行的shell脚本,如下图。
2、编写Java程序
本次编写的Java程序是基于ProcessBuilder调用shell脚本,可谓是非常简单明了了~
示例代码如下:
/** * java程序调用shell脚本 */ public void autoRunShell(){ try{ log.info("autoRunShell start......"); //要执行的shell脚本命令文件 String command = "./test.sh"; //要执行的命令所在目录path String path = "/data/service-control/backup"; //1.执行命令,要先切换目录 ProcessBuilder processBuilder = new ProcessBuilder(); //切换目标目录 processBuilder.directory(new File(path)); //添加要执行的命令 processBuilder.command(command); Process ps = processBuilder.start(); int execStatus = ps.waitFor(); //阻塞,直到上述命令执行完,返回为0则表示执行成功 log.info("autoRunShell execStatus:"+execStatus+",返回为0表示执行成功"); log.info("autoRunShell stop......"); }catch (Exception e){ log.error("autoRunShell:error:"+e.getMessage(),e); } }
3、运行Java程序
上面编写好了shell脚本以及Java程序后,只需要执行Java程序,就可以达到目的了,是不是很简单。
程序执行后的目录截图
PS:调用脚本时如果有权限问题的话,可通过下面的代码进行赋权。
赋权的代码:
/** * java程序调用shell脚本,并且附带权限控制 */ public void autoRunShellWithChmod(){ try{ log.info("autoRunShellWithChmod start......"); //要执行的命令 String command = "./test.sh"; //要执行的命令所在目录path String path = "/data/service-control/backup"; //0.赋权:如果权限不够的话,需要先赋权 ProcessBuilder processBuilder0 = new ProcessBuilder("/bin/chmod","755",command); processBuilder0.directory(new File(path)); Process ps0 = processBuilder0.start(); int chmodStatus = ps0.waitFor(); //阻塞,直到上述命令执行完 log.info("autoRunShellWithChmod chmodStatus:"+chmodStatus+",返回为0表示赋权成功"); //1.执行命令,要先切换目录 ProcessBuilder processBuilder = new ProcessBuilder(); //先切换目标目录 processBuilder.directory(new File(path)); processBuilder.command(command); Process ps = processBuilder.start(); int execStatus = ps.waitFor(); //阻塞,直到上述命令执行完,返回为0则表示执行成功 log.info("autoRunShellWithChmod execStatus:"+execStatus+",返回为0表示执行成功"); log.info("autoRunShellWithChmod stop......"); }catch (Exception e){ log.error("autoRunShellWithChmod:error:"+e.getMessage(),e); } }
编码不易,不喜勿喷~
-
linux – 在/etc/init.d脚本中调用守护进程是阻塞的,而不是在后台运行
2021-05-11 11:15:38我有一个我想要守护的Perl脚本.基本上这个perl脚本每隔30秒读取一个目录,读取它找到的文件,然后处理数据.为了简单起见,请考虑以下Perl脚本(称为synpipe_server,在/usr/sbin /中有此脚本的符号链接):#!/usr/bin/perl... -
Linux系统启动脚本执行顺序介绍
2021-05-13 14:02:58Linux系统启动脚本执行的顺序是有特定的规则的,今天美联科技小编就来跟大家介绍下Linux系统启动脚本执行的顺序。1、一般内核启动后1)先识别存储器分区,根据root=/dev/block/mtd/mmcblk0p6这样的的参数挂载文件系统... -
Linux下自启动脚本无效的解决办法!
2021-05-11 02:48:37Linux下自启动脚本无效的解决办法!(2009-01-06 14:40:58)标签:it今天有个工作,安装某台服务器,并部署相关程序!全部完成以后,我需要在开机时候自己启动apache和mysql,所以我自己写了一个文件,文件名姑且定为... -
linux后台执行命令(非阻塞):&和nohup
2021-05-11 11:15:35当我们在终端或控制台工作时,可能不希望由于运行一个作业而占住了屏幕,因为可能还有更重要的事情要做,比如...换成2>&1,&与1结合就代表标准输出了,就变成错误重定向到标准输出 linux后台执行命令(非阻塞):&和nohup -
Linux Shell脚本如何实现多线程
2021-05-11 03:26:13当我们工作中遇到一些批量分发、批量执行场景时,写的一些shell脚本都是单线程任务,当然这些量级不大的时候,看不出劣势。举个例子:现在需要通过跳板机,分发一个文件到10台服务器,每台服务器传输需要1s时间,10... -
Java调用linux shell脚本的方法
2021-05-15 04:37:00接下来,我们看一下java调用linux shell脚本的方法:首先,我们需要增加用户对该脚本的执行权限,即Stringcmdstring="chmoda+xtest.sh";Processproc=Runtime.getRuntime().exec(cmdstring);proc.waitFor();//阻塞,... -
linux脚本:ssh 启动多个远程程序
2021-05-12 09:18:31如果直接#!/bin/bashssh 192.168.49.1 '/home/geohpc/run_gdcnmsrv.sh'ssh 192.168.49.2 '/home/geohpc/run_gdcnmsrv.sh'ssh 192.168.49.3 '/...其他命令阻塞。而且断开终端远程程序会停止解决方法就是忽略终端关闭... -
如何使用shell脚本实现监控程序消息队列阻塞情况?
2021-05-11 11:16:13RT我想写个脚本来监控一个程序的消息队列是否阻塞我现在不知道要监控程序的代码结构。要从哪些方面可以监控出来呢???请教高手|用ipcs-q可以列出消息队列状态,然后用awk等工具取出队列长度,超过阈值就可以报警... -
Linux:shell脚本反复运行同一个程序
2021-05-11 02:45:45描述:写了一个检测脚本运行ffmpeg程序,当程序运行结束后继续运行该ffmpeg程序。思路:起初想要持续检测正在运行的进程,如果进程正在进行就什么也不做,该进程结束就重启该进程。写的脚本如下:#!/bin/bash#sh ... -
在linux后台运行脚本命令和程序的方法大全
2019-10-27 14:50:50linux提供了很多方法可以直接将普通的命令、脚本、应用程序以后台的形式运行起来,这样就不会阻塞终端窗口的继续使用。常用的涉及后台执行的命令有十几多个,包括:&、ctrl+z、bg、fg、nohup、disown、... -
linux 限制两个shell脚本同时执行
2021-05-11 12:55:03问题出现的原因,由于现在发版是用通过执行脚本,都会都过mvn打包,同时执行导致问题。解决方案在脚本执行前,检查、加锁、、、#!/bin/bash{flock-n3if[$?-eq1]thenecho"othershrunning"while[1]doflock-n3[$?-ne1]&... -
[Linux] 执行但不阻塞 以‘后台‘模式启动程序或脚本
2020-12-18 01:16:10例如启动一个脚本,执行 ‘./idea.sh’ 以启动idea,但终端会被阻塞,若终端被关闭,idea也就被关闭。 此时,执行 ‘./idea.sh &’ 可以使 idea 脱离当前终端运行,即便当前终端被关闭,idea也不会受影响。 ./... -
Linux-Shell脚本并发及并发数的控制
2022-02-25 15:43:47需求:100个shell脚本任务,同时不超过20个并发执行,通过shell脚本实现。 使用linux管道文件特性制作队列,控制线程数目 知识储备: 一.管道文件 1:无名管道(ps aux | grep nginx) 2:有名管道(mkfifo /tmp/fd1)... -
用java代码执行linux命令(shell脚本)
2020-04-27 09:14:25在windows下面编写java代码,然后打包放到Linux下面运行,并且执行某个脚本。 Runtime.getRuntime().exec("xxx.sh").waitFor(); 通过RunTime.getRuntime().exec()调用服务器命令脚本来执行。 用法: // 在单独的... -
java项目打的包在linux系统执行,启动linux脚本命令
2020-08-11 14:43:54废话少说,上代码,第一个测试命令发送了,但是脚本没有启动,第二个脚本启动ok,可以多个参数 ,参数在一个命令中发出的,看linux脚本命令需要的格式给,支持多个命令发送的,多命令用 ";"隔开,说的再多都没用,你... -
java 调用bash shell脚本阻塞的小问题的解决
2021-02-28 19:07:35java 调用bash shell脚本阻塞的小问题的解决背景使用java实现的web端,web端相应用户的界面操作,使用java调用bash实现的shell脚本进行实际的操作,操作完成返回执行结果给web 界面显示。现象:Java 进程阻塞。使用... -
QT 调用执行 linux脚本的三种方法
2018-10-16 13:51:20在linux系统下,Qt执行shell命令的方式有3种: (1)QProcess:execute("ls"); (2)system("ls"); (3)QProcess *process = new QProcess(); process->start("ls"); 注1... -
linux后台执行脚本(rabbitmq队列用的阻塞等待)
2018-11-15 00:34:351、nohup php 1.1getpullinfo.php & 输出的信息会被保存到nohup.out文件里 2、将信息保存到黑洞里(其实就是没有) nohup ./program >/dev/null 2>&1 & -
谢烟客---------Linux之bash脚本编程---用户交互
2021-05-12 14:54:41系统管理部分一:分区、创建、查看、调整、挂载、文件系统的结构、硬链接、软链接脚本"语法错误"非逻辑错误检测:# bash -n script.sh单独执行,脚本执行每个代码# bash -x script.sh+ 程序在执行没有+ 程序过程中... -
linux shell脚本中调用另一个shell脚本
2020-01-09 06:58:091.fork: 如果脚本有执行权限的话,path/to/foo.sh。如果没有,sh path/to/foo.sh。 2.exec:exec path/to/foo.sh 3.source:source path/to/foo.sh fork fork是最普通的, 就是直接在脚本里面用path/to/foo.sh来... -
C语言 linux信号和阻塞 sigaction函数
2021-05-15 16:28:111. 信号掩码——被阻塞的信号集每个进程都有一个用来描述哪些信号传送来将被阻塞的信号集,如果某种信号在某个进程的阻塞信号集中,则传送到该进程的此种信号将会被阻塞。当前被进程阻塞的信号集也叫信号掩码,类型... -
linux 定时传送文件 scp脚本实现自动输密码并传送
2022-04-15 09:07:03[root@fqdn soft]/usr/expect/bin/expect 显示如下图即为安装正常(出现 expect1.1) 二、expect的使用 示例:例如定时将数据库备份文件发送到另一台服务器 1、编写脚本 脚本一:用于传参数到第二个脚本 比如:... -
linux y脚本,Linux中脚本的使用方法
2021-05-15 11:46:16Linux中脚本的使用方法一、前言关于Linux中的脚本的用法,一直没有时间去好好地总结,正好今天下雨,就好好的整理一下思路吧,其实精通了一门语言,比如C语言,学习其他语言需要的成本是非常少的,同样的脚本作为一... -
使用Debian系linux脚本修改interfaces文件实现永久修改ip地址
2020-07-30 18:20:52此脚本执行相应的ifconfig和ip命令,并修改interfaces文件,通过接收参数的方式,实现对网络参数的修改(包括即时修改和永久修改)。