标签归档:shell

实用的Linux SHELL面试问题及答案

<

div id=”content” contentScore=”2213″>着之前有关面试的系列文章,读者的反应比较强烈,所以我决定出一篇有关Linux Shell相关的面试文章,如果对本文有什么意见或意见的话,欢迎反馈到我的邮箱里。

如果想要阅读已发表在Tecmint.com的文章,可以点击链接,链接到访谈系列,在这里我们已经介绍很多题目即文章。,FTP,MySQL和Apache的,脚本,Linux命令等。

Questions on Shell Scripting

Linux Shell脚本的10个有用的“面试问题和解答” http://www.linuxidc.com/Linux/2014-05/102374.htm

Linux Shell参数替换 http://www.linuxidc.com/Linux/2013-06/85356.htm

Shell for参数 http://www.linuxidc.com/Linux/2013-07/87335.htm

Linux/Unix Shell 参数传递到SQL脚本 http://www.linuxidc.com/Linux/2013-03/80568.htm

Shell脚本中参数传递方法介绍 http://www.linuxidc.com/Linux/2012-08/69155.htm

Shell脚本传递命令行参数 http://www.linuxidc.com/Linux/2012-01/52192.htm

实用的shell脚本面试问题

这边提到的5个面试问题,延续之前的有关Linux面试问题和答案。如果你是Tecmint.com的读者,你的支持我非常感谢。

1. 写一个shell脚本来得到当前的日期,时间,用户名和当前工作目录。

答案 : 输出用户名,当前日期和时间,以及当前工作目录的命令就是logname,date,who i am和pwd。

现在,创建一个名为userstats.sh文件,将下面的代码添加到它。

  1. #!/bin/bash
  2. echo “Hello, $LOGNAME”
  3. echo “Current date is `date`”
  4. echo “User is `who i am`”
  5. echo “Current directory `pwd`”

给它添加执行权限,并且执行他。

  1. # chmod 755 userstats.sh
  2. # ./userstats.sh

样例输出

  1. Hello, avi
  2. Current date isSatJun713:05:29 IST 2014
  3. Useris avi pts/02014060711:59(:0)
  4. Current directory /home/avi/Desktop

2.写一个shell脚本,进行两个数字的相加,如果没有输入参数就输出错误信息和一行使用说明

答案 : 下面是简单的shell脚本以及描述,如果没有命令行参数,它会抛出错误与如何使用脚本的说明。

再创建一个名为twonumbers.sh文件和下面的内容添加到文件里。

  1. #!/bin/bash
  2. # The Shebang
  3. if[ $# -ne 2 ]
  4. # If two Inputs are not received from Standard Input
  5. then
  6. # then execute the below statements
  7. echo “Usage – $0 x y”
  8. # print on standard output, how-to use the script (Usage – ./1.sh x y )
  9. echo ” Where x and y are two nos for which I will print sum”
  10. # print on standard output, “Where x and y are two nos for which I will print sum ”
  11. exit1
  12. # Leave shell in Error Stage and before the task was successfully carried out.
  13. fi
  14. # End of the if Statement.
  15. echo “Sum of $1 and $2 is `expr $1 + $2`”
  16. # If the above condition was false and user Entered two numbers as a command Line Argument,
  17. it will show the sum of the entered numbers.

给他添加可执行权限,并且执行。

  1. # chmod 755 two-numbers.sh

情形一: 未输入两个数字作为命令行参数运行脚本,你将得到下面的输出。

样例输出

  1. # ./two-numbers.sh
  2. Usage./twonumbers.sh x y
  3. Where x and y are two nos for which I will print sum

情形二: 当数字存在时,你会得到如图所示的结果。

  1. $ ./twonumbers.sh 45
  2. Sum of 4and5is9

因此,上述shell脚本满足了问题的要求。

3.你需要打印一个给定的数字的反序,如输入10572,输出27501,如果没有输入数据,应该抛出错误和使用脚本说明。在此之前,告诉我你需要在这里使用的算法。

算法

  1. 输入的数字为n
  2. 赋值 rev=0, sd=0 (反向和单个数字设置为0)
  3. n % 10, 将得到最左边的数字
  4. 反向数字可以用这个方法生成 rev * 10 + sd
  5. 对输入数字进行右位移操作(除以10)
  6. 如果n > 0, 进入第三步,否则进行第七步
  7. 输出rev

现在,创建一个名为numbers.sh</strong>文件,并添加以下代码。

  1. #!/bin/bash
  2. if[ $# -ne 1 ]
  3. then
  4. echo “Usage: $0 number”
  5. echo ” I will find reverse of given number”
  6. echo ” For eg. $0 0123, I will print 3210″
  7. exit1
  8. fi
  9. n=$1
  10. rev=0
  11. sd=0
  12. while[ $n gt 0]
  13. do
  14. sd=`expr $n % 10`
  15. rev=`expr $rev * 10 + $sd`
  16. n=`expr $n / 10`
  17. done
  18. echo “Reverse number is $rev”

授予对文件的执行权限,并运行如下所示的脚本。

  1. # chmod 755 numbers.h

情形一: 当输入不包含命令行参数,你将得到下面的输出。

样例输出

  1. ./numbers.sh
  2. Usage:./numbers.sh number
  3. I will find reverse of given number
  4. For eg../2.sh123, I will print321

情形二: 正常输入

  1. $ ./numbers.sh 10572
  2. Reverse number is27501

上面的脚本非常完美,输出正是我们需要的。

4. 你应该直接用终端,而不是依靠任何shell脚本来进行实数计算。你会怎么做(比如实数7.56+2.453)?

答案 : 我们需要用如下所述的特殊方式使用bc命令。将7.56+2.453作为输入通过管道进入bc中。

  1. $ echo 7.56+2.453| bc
  2. 10.013

5. 你需要给出圆周率的值,精度为小数点后100位,什么是最简单的方法。

答案 : 找圆周率的值最简单的方法,我们只是需要发出以下命令。

  1. # pi 100
  2. 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067

很明显!安装我们必须有包pi。只用一个aptyum命令,就能获得所需的软件包,同时用最简单方法来实现这个需求。

就是这样。我会很快在Tecmint.com发表另一个有趣的文章。至此敬请关注。别忘了向我们提供您在的评论和叼/div>

10个 Linux/Unix下 Bash 和 KSH shell 的作业控制实例

<

div id=”content” contentScore=”1525″>Linux 和 Unix 属于多任务的操作系统,也就是说一个系统在同一时间段内能运行多重任务(进程)。在这个新的博客系列,我将会列出相关的 Linux 和 Unix 作业(job)控制的命令,你可以通过这些命令在 Bash 或 Korn 还有 POSIX shell 下实现执行多重任务。

什么是作业控制?

作业控制不只是能够停止/挂起(stop/suspend)正在执行的进程(命令),也可以继续/唤醒(continue/resume)执行你需要的每一个进程。这完全可以用你的操作系统和 bash/ksh 之类的 shell 或 POSIX shell 完成。

谁给作业控制的提供了环境?

Bash / Korn shell,或者是 POSIX shell 提供给了作业控制的环境。

跟作业表打个招呼吧

你的 shell 会留有一张当前作业的表单,称为作业表。当你键入命令时,shell 会给它分配一个 jobID(也称作 JOBSPEC)。一个 jobID 或 JOBSPEC只是很小的整数数值。

#1: 创建你的首个 Linux/Unix 作业

我要运行一个名为 xeyes 的命令,它会在屏幕上显示两个椭圆的眼睛,输入: $ xeyes &

输出样例:

Fig.01: 在后台运行 xeyes 命令

我使用&符号让一个 job 在后台运行。shell 会打印一行信息类似如下:

  1. [1]6891

在这个例子中,有两个数字输出,分别表示:

  • 1 : 在后台执行的 xeyes 任务的作业号为 1。
  • 6891 : 作业1的进程ID。

我在多执行一些 job:

  1. ## 启动一个文本编辑器,X 的系统负载显示,和 sleep 命令 ##
  2. gedit /tmp/hello.c &
  3. xload &
  4. sleep 100000&

#2: 列出当前的作业

要查看当前 shell 的激活的任务状态,输入:

  1. $ jobs
  2. $ jobs l

输出如下:

  1. [1]9379Running xeyes &
  2. [2]9380Running gedit /tmp/hello.c &
  3. [3]-9420Running xload &
  4. [4]+9421Running sleep 100000&

简要描述如下:

字段 描述 示例
1 [1] jobIDJOB_SPEC – 工作号要与fg, bg, wait, kill和其他shell命令一起使用。你必须在工作号前缀添加一个百分号:(%)。
加号 (+) 标识着默认的或是现在的作业。
减号 (-) 标识着前一个作业。
%1
fg %1
kill %2
2 9379 进程 ID – 系统自动为每个进程创建并分配地独有的身份标志号。 kill 9379
3 Running 状态 – 关于作业的状态:
Running – 该 作业正在运行,还没有被外部信号挂起。
Stopped – 该作业已经被挂起。
N/A
4 xeyes & command – 由shell给出的命令。 script &
firefox url&

你也可以用 ps 命名列出当前系统正在运行的进程:

  1. $ ps

#3: 停止或挂起正在运行的作业

按下[Ctrl]-[Z]键或使用kill 命令,如下所示:

  1. kill s stop PID

举个例子,启动ping 命令,然后用 Ctrl-Z 键来停止 ping 弯div>

子shell与export命令

<

div id=”content” contentScore=”597″>登录到系统后,系统将启动一个用户shell。在这个shell中,可以使用shell命令或声明变量,也可以创建并运行shell脚本程序。运行shell脚本程序时,系统将创建一个子shell。此时,系统中将有两个shell,一个是登录时系统启动的shell,另一个是系统为运行脚本程序创建的shell。当一个脚本程序运行完毕,它的脚本shell将终止,可以返回到执行该脚本之前的shell。从这种意义上来说,用户可以有许多shell,每个shell都是由某个shell(称为父shell)派生的。

在子shell中定义的变量只在该子shell内有效。如果在一个shell脚本程序中定义了一个变量,当该脚本程序运行时,这个定义的变量只是该脚本程序内的一个局部变量,其他的shell不能引用它,要使某个变量的值可以在其他shell中被改变,可以使用export命令对已定义的变量进行输出。export命令将使系统在创建每一个新的shell时定义这个变量的一丼/div>

Linux shell脚本程序:天气预报

学习Linux shell以来,第一个完整的脚本程序,参考了网友的代码,修改了一些重要的错误,继续加油
#!/bin/bash
#weather.sh
#使用方法 weather.sh 城市,默认城市为上海
if [ -n “$1” ]
then
place=”$1″
else
place=”上海”
fi
rm -f index.shtml
wget -q http://weather.sina.com.cn/text/index.shtml
iconv -f gb18030 -t utf8 -o index index.shtml
ifzhixia=$(grep “$place” -c index)
if (($ifzhixia==2))
then
cat index | grep “$place” -A 3 |sed ‘1,2d’ | grep ‘>.\+’ > .weathertemp2
elif (($ifzhixia==1))
then
cat index | grep “$place” -A 3 | sed ‘1d’ |grep ‘>.\+’ > .weathertemp2
else
echo “没有该城市的天气讯息!”
exit 0
fi
condition=”天气状况: “
wind=”风向风力: “
tempr=”最高温度: “
echo “$condition” > .weathertemp
echo “$wind” >> .weathertemp
echo “$tempr” >> .weathertemp
echo -e “$pl

Linux编写shell脚本之for语句应用案例

<

div id=”content” contentScore=”392″>Linux编写shell脚本之for语句应用实例

依次列出三条文字信息,包括一天中的 morning noon evening 字串

Linux编写shell脚本之for语句应用案例

对使用 /bin/bash 作为登录shell的系统用户,检查他们在/opt目录中拥有的子目录或文件数量,如果超过100个,则列出具体数值及对应的用户账号

Linux编写shell脚本之for语句应用案例

计算 /etc目录中所有 *.conf 形式的配置文仼/div>

shell for参数

关于shell中的for循环用法很多,一直想总结一下,今天网上看到上一篇关于for循环用法的总结,感觉很全面,所以就转过来研究研究
1、 for((i=1;i<=10;i++));do echo $(expr $i \* 4);done
2、在shell中常用的是 for i in $(seq 10)
3、for i in `ls`
4、for i in ${arr[@]}
5、for i in $* ; do
6、for File in /proc/sys/net/ipv4/confaccept_redirects:’
18.for File in /proc/sys/net/ipv4/conf/*/accept_redirects; do
19.echo $File
20.done
21.echo “直接指定循环内容”
22.for i in f1 f2 f3 ;do
23.echo $i
24.done
25.echo
26.echo “C 语法for 循环:”
27.for (( i=0; i<10; i++)); do
28.echo $i
29.done

———————————————————————————————————
shell中for循环用法
shell语法好麻烦的,一个循环都弄了一会 ,找了几个不同的方法来实现输出1-100间可以被3整除的数
1.用(())
#!/bin/bash
clear
for((i=1;i<100;i++))
for
do
if((i%3==0))
then
echo $i
continue
fi
done
2.使用`seq 100`
#!/bin/bash
clear
for i in `seq 100`
do
if((i%3==0))
then
echo $i
continue
fi
done
3.使用while
#!/bin/bash
clear
i=1
while(($i<100))
do
if(($i%3==0))
then
echo $i
fi
i=$(($i+1))
done

——————————————————————————————————–
在shell用for循环做数字递增的时候发现问题,特列出shell下for循环的几种方法:
1.
for i in `seq 1 1000000`;do
echo $i
done
用seq 1 10000000做递增,之前用这种方法的时候没遇到问题,因为之前的i根本就没用到百万(1000000),因为项目需要我这个数字远大于百万,发现用seq 数值到 1000000时转换为1e+06,根本无法作为数字进行其他运算,或者将$i有效、正确的取用,遂求其他方法解决,如下
2.
for((i=1;i<10000000;i++));do
echo $i
done
3.
i=1
while(($i<10000000));do
echo $i
i=`expr $i + 1`
done
因为本方法调用expr故运行速度会比第1,第2种慢不少不过可稍作改进,将i=`expr $i + 1`改为i=$(($i+1))即可稍作速度的提升,不过具体得看相应shell环境是否支持
4.
for i in {1..10000000;do
echo $i
done
其实选用哪种方法具体还是得由相应的shell环境的支持,达到预期的效果,再考虑速度方面的问题。
示例:
# !/bin/sh
i=1
function test_while(){
i=1
while [ $i ]
do
echo $i
i=`expr $i + 1`
if [ $i -ge 10 ]; then
break
fi
done
}
function test_for(){
i=1
for ((i=1; i<=100; i++)); do
echo $i
if [ $i -ge 10 ]; then
break
fi
done
}
function test_continue(){
i=1
for i in $(seq 100); do
if (( i==0 )); then
echo $i
continue
fi
done
}
echo “test_while…”
test_while
echo “test_for…”
test_for
echo “test_continue…”
test_continue
运行结果:
test_while…
1
2
3
4
5
6
7
8
9
test_for…
1
2
3
4
5
6
7
8
9
10
test_continue…
10
20
30
40
50
60
70
80
90
100

相关阅读

Linux下Shell编程——awk编程 http://www.linuxidc.com/Linux/2013-06/85527.htm

Linux下Shell编程——sed命令基本用法 http://www.linuxidc.com/Linux/2013-06/85526.htm

Linux下Shell编程——grep命令的基本运用 http://www.linuxidc.com/Linux/2013-06/85525.htm<

shell 批量添加用户健壮版

网上传说,曾经有一道迅雷的笔试题,批量添加用户。做法很简单,有个小小的知识点。如何无交互的为用户设置密码。有两种方案:1、expect 2、passwd –stdin 。第一种通用,第二种非RedHat相关版本可能无法使用。大道至简,用第二种。也看到过网上的相关脚本。感觉不太完善,至少,如果添加的用户中,原本有一个已经存在,那么怎么办。很多人都没有处理。对于一个有代码洁癖的Coder。我决定自己写一个。上代码:

#!/bin/bash
#load system functions
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
for i in `seq -w 10`
do
        #generate passwd,8 random chars
        passwd=`echo $(date +%t%N)$RANDOM|md5sum|cut -c 2-9`
        #check wheather the username is in the /etc/passwd
        #important awk use the shell variable
        check=`awk -F ‘:’ ‘/^’gccmx$i’/ {print $1}’ /etc/passwd`
        if [ -z “$check” ];then
                useradd gccmx$i &>/dev/null && user_status=$?
                echo $passwd | passwd –stdin gccmx$i &>/dev/null && passwd_status=$?
        else
                user_status=1
                passwd_status=1
        fi
        if [ “$user_status” -eq 0 -a “$passwd_status” -eq 0 ];then
                action “The user gccmx$i is add successfully!” /bin/true
                echo -e “username:gccmx${i}tpassword:${passwd}” >>/tmp/userinfo.txt
        else
                action “The user gccmx$i is add faild!” /bin/false
                echo -e “username:gccmx${i}tpassword:${passwd}” >>/tmp/faild_info.txt
        fi
        unset user_status && unset passwd_status
        sleep 1
done

运行效果(gccmx05,已经存在,所以添加失败,用户名密码信息存储在/tmp/user_info.txt里):

相关阅读

自动备份脚本 Linux shell 第二版 http://www.linuxidc.com/Linux/2012-11/74219.htm

Linux/Unix shell 脚本中调用SQL,RMAN脚本 http://www.linuxidc.com/Linux/2012-09/70310.htm

Linux/Unix shell sql 之间传递变量 http://www.linuxidc.com/Linux/2013-01/78811.htm

Linux命令之sleep – 延迟指定时间 http://www.linuxidc.com/Linux/2011-04/3

shell编写动态页面

shell编写动态页面,听起来好搞笑,确实 实现起来也很搞笑。举个例子我想通过web页面展示我网站每小时的pv数 以及500错,当然统计pv数和500错 这要统计前台的nginx访问日志来得到。

答题思路
因为我们前台有4台nginx,我要首先合并每小时的4台nginx日志,统计出pv数和500错,然后把值传到我的web服务本机,具体脚本如下。

一.nginx日志合并所在服务器上编写脚本如下
#!/bin/bash
time=`date +%Y%m%d%H -d “-1 hour”`

rsync -av 192.168.0.20::logs/access.log.$time /backup/nginxlog/20/

rsync -av 192.168.0.149::logs/access.log.$time  /backup/nginxlog/149/

rsync -av 192.168.0.148::logs/access.log.$time  /backup/nginxlog/148/

rsync -av 192.168.0.48::logs/access.log.$time  /backup/nginxlog/48/

cd /backup/nginxlog

logs=`find ./ -name access.log.$time`

cat  $logs  >  /backup/nginxlog/agghour/access.log.$time.temp

grep jwml? /backup/nginxlog/agghour/access.log.$time.temp|wc -l>/opt/yanchao/huoqupv.txt
awk ‘$9~/500/{print}’ /backup/nginxlog/agghour/access.log.$time.temp|wc -l>/opt/yanchao/huoqu500.txt
awk ‘{++a[$1]}END{for ( i in a )print i,a[i]}’ /backup/nginxlog/agghour/access.log.$time.temp|sort -k2 -rn |head -n10|awk ‘{print $1}’>/opt/yanchao/tongji.txt
awk ‘{++a[$1]}END{for ( i in a )print i,a[i]}’ /backup/nginxlog/agghour/access.log.$time.temp|sort -k2 -rn |head -n10|awk ‘{print $2}’>/opt/yanchao/cishu.txt

cat  /backup/nginxlog/agghour/access.log.$time.temp  |sort -k 4  >  /backup/nginxlog/agghour/access.log.$time

rm -f /backup/nginxlog/agghour/access.log.$time.temp

rm -f /backup/nginxlog/20/* && rm -f /backup/nginxlog/149/* && rm -f /backup/nginxlog/148/*  &&  rm -f /backup/nginxlog/48/*

二.在web服务器上起个80端口
在web根目录新建index.html

 

 

 

 

 

新建index1.html
 

 <\tr>
Time Count PV 500error

编写脚本如下
#!/bin/bash
rm -f /var/www/html/index1.html
cp /var/www/html/index2.html /var/www/html/index1.html
rm -f /var/www/html/test.txt
c=`cat /opt/yanchao/pv.txt`
a=`date +%H:00 -d ‘-1 hour’`
b=`date +%H:00`
g=`cat /opt/yanchao/500.txt`
echo -e “$a-$b\t$c\t$g\t” >/var/www/html/test1.txt
e=($(awk ‘{print $1}’ /var/www/html/test1.txt))
f=($(awk ‘{print $2}’ /var/www/html/test1.txt))
d=($(awk ‘{print $3}’ /var/www/html/test1.txt))

for ((i=0;i<=${#e[@]};i++))
do
      echo  “

${e[i]}

” >>/var/www/html/test.txt
      echo  “

${f[i]}

” >>/var/www/html/test.txt
      echo  “

${d[i]}

” >>/var/www/html/test.txt
      echo -e “\n”
done
sed -i ‘/

/r /var/www/html/test.txt’ /var/www/html/index1.html
echo `cat /var/www/html/index.html` >> /var/www/html/linuxidc.html
echo `cat /var/www/html/index1.html` >> /var/www/html/linuxidc.html

三.新建获取数值脚本
#!/bin/bash
ssh 192.168.0.96 “cat /opt/yanchao/huoqupv.txt” >/opt/yanchao/pv.txt
ssh 192.168.0.96 “cat /opt/yanchao/huoqu500.txt” > /opt/yanchao/500.txt
ssh 192.168.0.96 “cat /opt/yanchao/tongji.txt” > /opt/yanchao/tongji.txt
ssh 192.168.0.96 “cat /opt/yanchao/cishu.txt” > /opt/yanchao/cishu.txt

添加crontab
8 * * * * (sh /opt/yanchao/huoqu.sh &)

最后访问linuxidc.html

推荐阅读:

Linux/Unix shell 脚本中调用SQL,RMAN脚本 http://www.linuxidc.com/Linux/2012-09/70310.htm

Linux/Unix shell sql 之间传递变量 http://www.linuxidc.com/Linux/2013-01/78811.htm

Linux命令之sleep – 延迟指定时间 http://www.linuxidc.com/Linux/2011-04/34758.htm

Linux下Shell编程——sed命令基本用法 http://www.linuxidc.com/Linux/2013-06/85526