王志勇 发表于 2019年09月11日 09:23
困难1. 本来最好的方法是用cat命令加反引号,可以读取整个文件,例如a1=`cat /etc/ssh/sshd_config`; 然后替换$a1变量的数据,再写入$a1变量,这个过程就和PHP完全一样。但是问题出现了,反引号里的数值,会自动把所有的回车符,变成空格。写入的时候,所有的回车符变成了空格。因此,这个方案行不通。
困难2. 改用while read line的方法,逐行读取,但是在while read line这个循环语句里,循环里的赋值不允许循环外调用,例如这样:
a1=333;
cat /etc/ssh/sshd_config | while read line;
do a1=555;
done;
echo $a1;
运行的结果是333。
为了证明循环里的赋值不允许循环外调用,在上述的程序 do a1=555; 这一行之后再加入一行 echo $a1; 让其显示此时$a1的值,果不其然,结果是:
555
555
……
555
555
555
333
而一般的循环语句里,则循环里的赋值,允许循环外调用,例如这样:
a1='1111'; for ((a=1;a<=5;a++)); do a1='2222'; done; echo $a1;
运行的结果是2222。
Shell程序,为什么要在while read和for语句里这样设置一个区别呢?
答案就是很可能困难1、困难2,都是因为Shell程序自身的bug。
Shell命令、Shell程序一个缺点是如果是作为公共项目,必须尽量用兼容性很强的语句。不能在这个系统下执行,另一个系统下不执行。例如我在项目里,最近遇到的一个不兼容的基本例子:
将所有字符转换成小写:
str=${str,,};
上述这个语句就可以把将所有字符转换成小写,在Ubuntu、Debian所有系统下自带的Bash正常运行;但是在CentOS系统下自带的Bash,就不运行。因此,这个语句就只能放弃,只能用这种方法,将所有字符转换成小写:
a1=$(echo 'CCC' | tr '[A-Z]' '[a-z]'); echo $a1;
Shell程序替换一个文件里的字符,3年多以前我花了很多时间测试方法,最后用的是这个方法,把文件中的所有fff替换成kkk,并写入文件:
sed -i "s/fff/kkk/g" /etc/data22.txt
用sed命令能实现。但是缺点是,如果需要替换多次,则需要写入多次文件,会导致硬盘频繁写入,影响计算机性能,或者增加数据写入出错的风险。(PHP等任何编程语言,则只需写入一次。)
如今又需要解决3年前的问题,现在依然只能用sed命令。
置顶的文章:
论朋友圈可以发什么?
短信验证开发的方案分享
巡回更新:2018-09-21
速度是永恒的主题
UTF-8、HTTPS原来都是浮云
https安全吗?
独立博客有必要安装https吗?
近期的主题:
夜晚靓歌(10):你没看过的《星雨心愿》
Feedval、Blogval将下线/谈理财和生存
2024.9感言
人生讨论(20):有人借钱怎么办?(2)
人生讨论(19):迄今为止最强的情感频道
数码评测(67):让小米/红米手机的反应提高1~2倍
数码评测(66):无线网卡FW150UH VS FW150UH
数码评测(65):如何快速自制CPU天梯图?
数码评测(64):2024年,你还在用VGA线吗?
人生讨论(18):6年就可以实现财务自由
人生讨论(17):为什么总是受欺负?
人生讨论(16):要钱的最新妙招
创业杂谈(17):什么项目能赢利?
人生讨论(15):有人借钱怎么办?
数码评测(63):高清切换超级神器
数码评测(62):再谈视频的尺寸
数码评测(61):近期数码采购和折腾
人生讨论(14):看穿尊重
数码评测(60):图拉丁-最佳中配工作“免费”手机
创业杂谈(16):博客何时终结?
版权声明:本博客所有文章,均符合原创的定义,禁止转载,违者将必究;正确的方法是贴原文的标题和网址即可。
与此相关的链接
自由勇专栏
Blog存档 Archives
2022年07月
2022年06月(15)
2022年05月(20)
2022年04月(16)
2022年03月(9)
2022年02月(9)
2022年01月(10)
2021年 +