shell脚本和命令调用

wget的断点续传

传大库时经常使用-c来实现断点续传,但如果远程文件被改动了,并且下次传库时文件名是相同的,那么就需要先删除或移动本地文件。这是因为wget无法验证本地文件跟远程文件是否是同一个,只能简单的通过文件名来判断。这就导致了如果新文件比本地文件大,就会只下载大于本地文件的那部分,并追加到本地文件末尾。反之则不下载。wget使用了"(length(remote) - length(local))" 这个公式计算续传部分大小。

当-c跟-r一起使用时需要特别注意这个“续传”的副作用。

 

wget下载大文件失败

——wget下载大于2G的文件失败

请查看wget是否低于1.10.X

* Changes in Wget 1.10.

** Downloading files larger than 2GB, sometimes referred to as "large files", now works on systems that support them. This includes the majority of modern Unixes, as well as MS Windows.

 

expr 做乘法运算报语法错误

——expr 做乘法运算为什么总是报语法错误?

a=5 expr $a *5总是报 expr: syntax error 错误使用乘号时,必须用反斜线屏蔽其特定含义。因为shell可能会误解显示星号的意义。 expr $a /* 5 这样就可以了:)

 

双引号里的单引号

——引号嵌套使用时内层引号无特殊意义

例如:

$a=1

$echo "hello '$a'"

1

如果需要显示为$a,则应该

echo "hello" '$a'

 

read导致的乱码?

日本同事在使用read读取文件时,发现读取后的字串变成了乱码,具体如下:

img@jp01-testing-image02.jp01.baidu.com bdimgfilter]$ cat hotphoto

黒川智花 http://t4.baidu.jp/it/u=9969239,3978260080

[img@jp01-testing-image02.jp01.baidu.com bdimgfilter]$ while read line; do echo $line; done <hotphoto

�川智花 http://t4.baidu.jp/it/u=9969239,3978260080

 

[黒川智花]中含有反斜杠字符,在使用脚本处理的时候被过滤所致.

man read

The backslash character (/) may be used to remove any special meaning for the next character read and for line continuation.

read有个选项: -r

-r Backslash does not act as an escape character. The backslash is considered to be part of the line.

 

使用 read –r就解决问题了.

[img@jp01-testing-image02.jp01.baidu.com bdimgfilter]$ while read -r line; do echo $line; done <hotphoto

黒川智花 http://t4.baidu.jp/it/u=9969239,3978260080

 

Windows下编写的脚本无法运行?

现象:在window下用记事本编辑一个shell脚本,传到linux下,脚本无法正常运行,出现错误提示:/bin/bash^M: bad interpreter: No such file or directory

原因:linux下不能识别windows下的回车符CR(回车),在ASCII表中,CR对应的控制符是^M,所以在window下编辑的文本在linux下的会有^M字符.而在linux下编辑的文本在windows下用记事本打开,会有黑色小方块

解决:进行格式转化dos2unix /unix2dos (推荐使用) Dos->unix: dos2unix filename Unix->dos: unix2dos filename 手工去掉^M Dos->unix: sed -e 's//r//g‘ Unix->dos: sed -e ‘s/$//r/g’

 

rm –f的隐患

现象: rm –f a.txt && echo “OK” 当a.txt不存在时,依然输出OK

原因: -f, --force ignore nonexistent files, never prompt -f 通常被理解为强制删除,和man中的解释还是有一定出入的,实际上应理解为忽略不存在的文件,从来不提示。

解决: 如果要区分文件是否存 先判断文件是否存在再删除 去掉-f,判断rm 的返回值

现象: 执行cd work;rm –rf * 发现用户当前目录下的所有文件都被删除了!

原因: cd work这条命令由于某种原因执行失败,没有切换目录就执行了rm –rf *,导致删除所有文件。分号“;”连接的两条命令是无条件顺序执行的,即使前面命令出错,下面的命令也会继续执行。

解决: cd work && rm –rf * && 连接的两条命令表示,只有在前面的命令执行成功时,才运行后面的命令。这样更加安全。 cd work 判断$?=0再执行rm –rf *

 

sort排序的诡异现象

现象:sort a.txt

1385940 1

1385943 502

1385944 1

138594 458 (期望结果此行应该在行首)‏

1385945 8

原因: 未设置locale时,默认按照en_US排序,sort命令会忽略特殊字符(标点,空格等),接着对下一个字节进行排序。所以例子中 1385944 1 排在138594 458前面。要想解决此问题需要对locale进行设置,或在sort命令中按照键来排序

解决: LC_ALL=C sort a.txt LC_ALL=C 按照字典排序,对于标点等字符也会根据在ASCII中的值进行比较。 sort -k1,1 a.txt 按第一列排序

 

脚本遭遇语法错误时…

现象: if [ $ret -ne 0 ] then echo “NO” exit fi echo “YES” 如果变量ret未设置或为空时,脚本不退出,而依然显示YES。

原因: 当ret为空时或未设置时,条件语句[ $ret –ne 0 ]出现语法错误,这时这个条件是不成立的(假),脚本继续运行下面的语句,如果有else则处理else中的语句。

解决: 如何避免这类语法错误? if [ ${ret:=1} -ne 0 ] then echo “NO” exit fi echo “YES” 这里如果变量ret为unset或为NULL时,先设置ret默认值为1(unset或NULL时按照 ret = 0处理),再进行比较。使用(( )),注意这里如果a未unset或NULL时,默认a=0处理 if((a == 0)) then echo "a = 0" fi

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java可以通过Runtime和ProcessBuilder类来调用Shell命令脚本。下面是一个简单的示例: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class ShellCommand { public static void main(String[] args) { try { // 执行Shell命令 Process process = Runtime.getRuntime().exec("ls -al"); // 读取Shell命令的输出 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } // 等待Shell命令执行完毕 int exitCode = process.waitFor(); System.out.println("Shell命令执行完毕,退出码为:" + exitCode); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 在上述示例中,我们通过Runtime类的exec()方法执行了一个Shell命令,然后通过Process类的getInputStream()方法获取了Shell命令的输出流,并通过BufferedReader类逐行读取了输出内容。最后,我们通过Process类的waitFor()方法等待Shell命令执行完毕,并获取了Shell命令的退出码。 类似地,我们也可以使用ProcessBuilder类来执行Shell脚本。以下是一个示例: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; public class ShellScript { public static void main(String[] args) { try { // 执行Shell脚本 ProcessBuilder builder = new ProcessBuilder(Arrays.asList("/bin/bash", "-c", "./test.sh")); Process process = builder.start(); // 读取Shell脚本的输出 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } // 等待Shell脚本执行完毕 int exitCode = process.waitFor(); System.out.println("Shell脚本执行完毕,退出码为:" + exitCode); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 在上述示例中,我们使用ProcessBuilder类创建了一个Shell进程,并指定了要执行的Shell脚本。然后通过Process类的getInputStream()方法获取了Shell脚本的输出流,并通过BufferedReader类逐行读取了输出内容。最后,我们通过Process类的waitFor()方法等待Shell脚本执行完毕,并获取了Shell脚本的退出码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值