Linux的Shell相关知识简要描述几种主流的shell及特点!!!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux的Shell相关知识简要描述几种主流的shell及特点!!!相关的知识,希望对你有一定的参考价值。

Linux系统管理与服务器配置这本书上,在228页第17章。。。
我是这么做的,大家可以参考参考。。
?在网上搜索Linux的Shell相关知识简要描述几种主流的shell及特点;
答:Linux是由UNIX演化而来的,从而也继承了UNIX的sell,在大部分的UNIX系统。三种著名且广被支持的Shell是:Bourne shell(AT&T shell,在Linux下是BASH),
C shell(Berkeley shell,在Linux下是TCSH),Korn shell(Bourne shell的超集)。三种shell各有优缺点
Bourne shell是标准的UNIIX shell,是UNIX最初使用的shell,并且在每种UNIX上都可以使用,常被用来作为管理系统之用,它简洁,快速,多用于shell编程方面,但与用户的交互性较差
C shell是一种比Bourne shell更适于编程的shell,它的语法与C语言很相似。 Linux为喜欢使用C shell的人提供了Tcsh。Tcsh是C shell的一个扩展版本,Linux下的C shell则更多的考虑到了用户界面的而友好性,
它支持不少新功能。例如:提供了一个命令列(command line)编辑程序,提供了命令列不全功能,提供了拼写更正功能。它能自动检测并更正在命令列拼错的命令或单字;
危险命令侦测并提醒的功能,避免用户小心执行rm*这种杀伤力极大的命令;提供常用命令的快捷方式
BASH shell是Linux下对Bourne shell向下兼容的一种shell,并融入许多C shell与Korn shell的功能
参考技术A 最常见的有:
Born shell: 最早,所有的Unix和Linux上肯定都能用
csh: 与C语言有些像,如果会C, 这个肯定觉得很容易
ksh: Korn shell, 比上两种要好。特别是可以修改指令行(command line editing), 真是不可少。
bash: Born again shell, 改进版的Born shell。大概是Linux上最常用的

个人认为从ksh或bash中选一即可。
参考技术B 什么是shell script

将OS命令堆积到可执行的文件里,由上至下的顺序执行文本里的OS命令 就是脚本了.

再加上些智能(条件/流控)控制,就变成了智能化脚本了.

变量

变量声明

bash中的变量无须声明,拿来就用.类型会根据赋予的值来决定

a=abc

b=123

c=(123)

d=$(uname -r)

unset a

declare -p var_name 可以查看

引用变量

在变量名前加上 $ 符号

echo $a

作用范围

全局

export var=abc

. 或 source

局部

子进程中

函数中

操作符

算术操作

+ - * / %

关系操作

< > <= >= == != && ||

测试操作

测试命令 test [ ] [[ ]] (( ))

1、测试文件状态

-d 目录

-s 文件长度 > 0、非空

-f 正规文件

-w 可写

-L 符号连接

-u 文件有 suid 位设置

-r 可读

-x 可执行

$ [ -w tmp.txt ]

$ echo $?

0

2、字符串测试

= 两个字符串相等

!= 两个字符串不相等

-z 空串

-n 非空串

$ VAR1='abc'

$ VAR2='123'

$ [ '$VAR1' = '$VAR2' ]

$ echo $?

1

3、测试数值

-eq 等于

-ne 不等于

-gt 大于

-lt 小于

-ge 大于等于

-le 小于等于

4. 拓展测试符号 [[ ]] (())

数字测试符号

# [ 10 < 2 ] # 语法错误

-bash: 2: 没有那个文件或目录

#

# [[ 2 > 10 ]] # 结果错误

# echo $?

0

# [[ 20 > 10 ]] # 正确

# echo $?

0

# (( 10 < 20 ))

# echo $?

0

字符测试

# [ "aa" = "aa" ]

# echo $?

0

# [[ "aa" = "aa" ]]

# echo $?

0

# (( "aa" = "aa" )) #结果错误

# echo $?

1

混合测试

# [ a = a -a 10 < 20 ]

-bash: 20: 没有那个文件或目录

结论:

比较数字,使用(( ))

其他测试使用 [[ ]]

包含数字比较的混合测试,使用标准语法

流控结构

if 分支结构

# cat my.sh

#!/bin/bash

var=/etc/init.d

if [[ -d $var ]]

then

echo "$var is directory."

elif [[ -b $var ]]

then

echo "$var is block device."

elif [[ -f $var ]]

then

echo "$var is a regular file."

else

echo "unknow."

fi

# 除了 -L -h 等于的文件测试遇到软连接都会用原文件测试

if 测试中还可以执行命令 根据命令的返回值做判断

# if cd / ;then echo Y ;fi

# if grep -q root /etc/passwd ;then echo Y ;fi

向脚本传递参数

# vim 2.sh

#!/bin/bash

echo '$0' $0

echo '$1' $1

echo '$2' $2

echo '$3' $3

echo '$10' $10

echo '$11' $11

echo '$12' $12

echo '$$' $$

echo '$*' $*

echo '$@' $@

echo '$#' $#

echo '$?' $?

# $@ $* 在双引号(软引用)参数中有差异,$@会将引号内的多个参数当成一个参数,这会影响到$#的数量

修改脚本从参数中传递测试文件

# cat 1.sh

#!/bin/bash

if [[ -d $1 ]]

then

echo "$1 is directory."

elif [[ -b $1 ]]

then

echo "$1 is block device."

elif [[ -f $1 ]]

then

echo "$1 is a regular file."

else

echo "unknow."

fi

#讲讲for i in 语法

检查内网存活的IP

#!/bin/bash

for i in 1..254

do

(ping -W 1 -c 1 192.168.1.$i &> /dev/null && echo 192.168.1.$i) &

done

让文件测试脚本支持多个参数

# vim 1.sh

#!/bin/bash

for i in $@

do

if [[ -d $i ]]

then

echo "$i is directory."

elif [[ -b $i ]]

then

echo "$i is block device."

elif [[ -f $i ]]

then

echo "$i is a regular file."

else

echo "unknow."

fi

done

修改脚本使脚本最多支持3个参数,多个参数或0个参数报错,并退出脚本.

[[ $# > 3 || $# = 0 ]] && echo "USAGE: $0 ERROR" && exit 1

使用测试

修改脚本告诉用户错误原因.

case 结构语法 用户登录欢迎

# cat 4.sh

#!/bin/bash

case $1 in

root)

echo "welcome $1"

;;

seker)

echo "welcome $1"

;;

*)

echo "no user $1"

esac

添加上与用户交互的功能

read -p "username: " uname

如果等待时间内用户没输入 则采用默认值

read -p "username: " -t 5 uname

echo

if [[ -z $uname ]]

then

uname=default

fi

case $uname in

root)

echo "welcome $uname"

;;

seker)

echo "welcome $uname"

;;

default)

echo "welcome $uname"

;;

*)

echo "no user $uname"

esac

再修改脚本 让用户输入密码

然后比对密码是否一致,如果不一致,则不显示欢迎信息

#cat 4.sh

#

read -p "username: " -t 5 uname

echo

stty -echo

read -sp "password: " paswd

stty echo

echo

if [[ -z $uname ]]

then

uname=default

fi

case $uname$paswd in

'root111')

echo "welcome $uname"

;;

'seker222')

echo "welcome $uname"

;;

'default333')

echo "welcome $uname"

;;

*)

echo "no user $uname"

esac

# case的字符测试还可以使用 | 结构 例如: a|b)

启动脚本

循环结构

while 语法

while (条件)

do

动作

done

需要无限循环时我们会选择while :

写个脚本 让用户输入,输入数字通过,输出错误重新输入

#!/bin/bash

retry=0

while [ $retry -eq 0 ]

do

read -p "enter a num : " aa

if expr $aa + 0 &> /dev/null

then

echo OK..

retry=1

else

echo "enter error.retry.."

fi

done

# cat 5.sh

#!/bin/bash

i=1

while (( $i < 10 ))

do

echo $i

((i++))

done

#

until 循环

# cat 6.sh

#!/bin/bash

i=1

until ! (( $i < 10 ))

do

echo $i

((i++))

done

# until是条件为假时进入循环

# while是条件为真时进入循环

# 对until条件取反 则等同于 while

C语言格式的for

for ((i=1;i<=10;i++))

do

echo $i

done

shell格式的for

for i in 1..10

do

echo $i

done

循环控制

# for i in 1..10;do [ $i -eq 5 ] && continue || echo $i;done

# for i in 1..10;do [ $i -eq 5 ] && break || echo $i;done

shift命令

# cat 8.sh

#!/bin/bash

while (($# != 0))

do

echo $1

shift

done

统计/dev下每种类型文件的数量

向脚本传递一个用户名,验证这个用户是否存在.

添加30个用户,再将它们删除

将$PATH中的找出所有加了SUID位的文件

FTP自动下载脚本

自定义函数

1.函数定义

shell允许将一组命令集或语句形成一个可用块,这些块称为shell函数

定义函数的格式:

function-name ()

command1

........



或 function function-name() #函数名前面多了个function关键字

command1

........



2.函数调用

以下是一个函数的脚本实例:

#!/bin/bash

#hello

function hello() #声明函数

echo "Hello!" #函数的主体,输出"Hello!"

#函数结束

hello #调用函数

3.参数传递

向函数传递参数就像在脚本是使用变量位置$1,$2,$3...$9

以下是一个传递参数的实例:

#!/bin/bash

#hellofun

function hello()

echo "Hello! The first parameter is '$1'."



hello good

#该脚本执行的结果是: Hello! The first parameter is 'good'.

4.函数文件

保存函数的文件,用以上的例子写成一个函数文件如下:

#!/bin/bash

#hellofunction

function hello()

echo "Hello!"

return 1



上面的hellofunction文件就是一个函数文件,可通过另一个脚本来调用

#!/bin/bash

#hellof

. hellofunction #注意点和hellofunction之间有个空格

hello

5.载入和删除

用set查看已载入的函数

用unset function-name 取消载入

举例如下:

#!/bin/bash

#hellof

. hellofunction

unset hello

hello #因为已经取消载入。。所以会出错

6.函数返回状态

#!/bin/bash

#hellofun

function hello()

echo "Hello! The first parameter is '$1'."

return 1



hello

echo $? #输出返回的状态值(一般成功是返回0,其它值为失败)

回收站 删

[root@stu254 dir]# cat /bin/del

#!/bin/bash

mkdir -p ~/.trash

for i in $*

do

$echo $i

mv -f $i ~/.trash

done &> /dev/null

[root@stu254 dir]#

回收站 恢复

[root@stu254 dir]# cat /bin/undel

#!/bin/bash

for i in $*

do

find ~/.trash -maxdepth 1 -name "$i" -exec mv . \;

done

[root@stu254 dir]#

数组

数组就是若干个变量组合在一起 每个变量的值都是数组的元素

元素都在数组中有一个下标 下标从0开始

数组赋值:

[root@stu254 dir]# ary=(root seker zorro blues pg)

取值方法:

第一个元素

[root@stu254 dir]# echo $ary[0]

root

[root@stu254 dir]#

第三个元素

[root@stu254 dir]# echo $ary[2]

zorro

[root@stu254 dir]#

所有元素

[root@stu254 dir]# echo $ary[*] ; echo $ary[@]

root seker zorro blues pg

root seker zorro blues pg

[root@stu254 dir]#

[root@stu254 dir]#

第二个到第四个元素

[root@stu254 dir]# echo $ary[*]:1:3

seker zorro blues

[root@stu254 dir]#

下标大于等于2的所有元素

[root@stu254 dir]# echo $ary[*]:2

seker zorro blues pg

[root@stu254 dir]#

下标小于2的所有元素

[root@stu254 dir]# echo $ary[*]::2

root seker

[root@stu254 dir]#

元素个数

[root@stu254 dir]# echo $#ary[*]

5

最后一个元素

[root@stu254 dir]# echo $ary[$(($#ary[*]-1))]

4pg

倒数第2个元素

[root@stu254 dir]# echo $ary[$(($#ary[*]-2))]

3blues

[root@stu254 dir]#

for批量对数组赋值

[root@stu254 dir]# ary=($(for i in 0..99;do echo $RANDOM;done))

[root@stu254 dir]# echo $#ary[*]

100

打印数组中所有的奇数和偶数

用数组个数中的奇数值覆盖偶数值,例如第1个元素覆盖第2个 第3个元素覆盖第4个元素

从文件中读取每行赋予一个数组的方法

生成随机数 赋予数组 进行排序

找出/etc/下最新的文件和最旧的文件 modify time

变量测试

$var-value 和 $var:-value

- 号 如果变量设置为空则返回空值

:-号 如果变量设置为空则返回临时值

变量没声明 则临时赋值,否则使用原值

[root@stu254 ~]#

[root@stu254 ~]# unset var

[root@stu254 ~]# echo $var-value

value

[root@stu254 ~]# echo $var:-value

value

[root@stu254 ~]# var=123

[root@stu254 ~]# echo $var-value

123

[root@stu254 ~]# echo $var:-value

123

[root@stu254 ~]# var=""

[root@stu254 ~]# echo $var-value

[root@stu254 ~]# echo $var:-value

value

[root@stu254 ~]#

+ 号 如果变量

[root@stu254 ~]# unset var

[root@stu254 ~]# echo $var+value

[root@stu254 ~]# echo $var:+value

[root@stu254 ~]# var=123

[root@stu254 ~]# echo $var+value

value

[root@stu254 ~]# echo $var:+value

value

[root@stu254 ~]# var=""

[root@stu254 ~]# echo $var+value

value

[root@stu254 ~]# echo $var:+value

[root@stu254 ~]#
参考技术C 哥们,我也是东软的,求解啊 参考技术D 哥们,东软的吧,我们今天考,我们施刚带的,你呢

Linux 基础知识 | shell知识

Linux 基础知识 | shell知识

Linux操作系统,需要使用shell程序将下达的指令去沟通内核(kernel),以便Kernel控制计算机硬件进行工作。其中shell程序发展者众,而Linux中默认的shellbash程序。本篇主要介绍bash的相关功能以及使用方式。

系统可用的shell

可以通过以下方式查看系统中可用的shell程序

[root@VM_16_15_centos ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh

可以通过查看/etc/passwd查看每个用户登录后使用的默认shell程序:

[root@VM_16_15_centos ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
...省略...

从上面的信息来看,默认情况下,root用户登录后使用的shell程序为/bin/bash,这个shell是本篇文章的主要内容。

Bash shell的主要优点

  • 命令记忆功能:bash会把上一次登录所执行过的指令都记录在~/.bash_history中,可以在命令行中按上下键就可以找到前一个或者后一个的指令了。
  • 命令补全功能:在某些时候我们只记得了某个命令或者文件的部分描述,比如开头几个单词,这个时候就可以使用命令补全功能了,通过按[tab]键即可自动列出所有可用的指令或者文件路径。
  • 命令别名功能,可以通过设置某个命令加参数为一个别名,然后可以通过别名执行该命令,例如一般情况下系统都会把ls -l设置一个ll的别名,这个时候我们只需要输入ll则可以达到ls -l的效果了。

命令别名

查看别名

[root@VM_16_15_centos ~]# alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

设置别名:

alias ll='ls -l'

取消别名

unalias ll

历史命令

查看历史命令:

history

执行上一条指令:

!!

执行history列表中的序号为937的指令

!937

执行最近一个以ca开头的指令

!ca

指令的搜寻顺序

当一个指令被下达的时候,会按照如下顺序寻找该指令:

  • 以绝对路径或相对路径执行,例如/bin/ls
  • alias找到指令执行
  • bash内置指令执行
  • 通过PATH变量顺序搜索到第一个指令执行

Bash shell环境变量

在登录进入Linux系统的时候,bash会读取一些配置文件,这些配置文件各自的作用都不一样,通常情况下,我们在安装一些软件的时候,要把某些路径加入环境变量,便于更方便的执行这些命令。

  • /etc/profile 系统整体的配置,一般情况下不需要修改这个文件
  • ~/.bash_profile或者~/.bash_login~/.profile是属于使用者个人设置。一般情况下,用户会修改这里的环境变量。

/etc/profile文件可以利用使用者的uid来设定一些变量,可以通过查看这个文件内容:

[root@VM_16_15_centos ~]# cat /etc/profile
# /etc/profile

# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc

# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.

pathmunge () 
    case ":$PATH:" in
        *:"$1":*)
            ;;
        *)
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac



if [ -x /usr/bin/id ]; then
    if [ -z "$EUID" ]; then
        # ksh workaround
        EUID=`/usr/bin/id -u`
        UID=`/usr/bin/id -ru`
    fi
    USER="`/usr/bin/id -un`"
    LOGNAME=$USER
    MAIL="/var/spool/mail/$USER"
fi

# Path manipulation
if [ "$EUID" = "0" ]; then
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
fi

HOSTNAME=`/usr/bin/hostname 2>/dev/null`
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL

# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
    umask 002
else
    umask 022
fi

for i in /etc/profile.d/*.sh ; do
    if [ -r "$i" ]; then
        if [ "$-#*i" != "$-" ]; then 
            . "$i"
        else
            . "$i" >/dev/null
        fi
    fi
done

unset i
unset -f pathmunge

这个文件设置的变量主要有:

  • PATH 会根据uid决定PATH变量是否包含sbin目录的命令
  • MAIL 根据账号设置mailbox/var/spool/mail/账号名
  • USER 设置账号变量
  • HOSTNAME 设置主机名变量
  • HISTSIZE 历史命令记录数量
  • unmask 一般用户

除了导入以上环境变量外,还会读取/etc/profile.d/*.sh去执行相关的shell script文件,这里面的shell scripts文件主要作用是规范了bash窗口的颜色、语系、ll别名、vi别名、which别名等相关操作。

~/.bash_profile或者~/.bash_login~/.profile文件则会在读完/etc/profile之后读取,这几个文件会按照顺序读取,如果读到了第一个文件,后面的文件就不会读取了(一般情况下都是.bash_profile`文件)

我们来查看下这个文件的内容:

[root@VM_16_15_centos ~]# cat ~/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

从输出的信息看,这个文件主要是在PATH变量中加入了~/bin目录,并且读取了~/.bashrc文件。

所以如果需要添加环境变量,则可以修改~/.bash_profile或者~/.bashrc文件,并且修改完之后需要调用source xxx让该文件生效。

下面在来看一下~/.bashrc内容

[root@VM_16_15_centos ~]# cat ~/.bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

其实这个文件会调用了/etc/bashrc文件,所以如果~/.bashrc文件丢失了之后,可能bash的提示字符会变成这样

-bash-4.2$

解决办法就是从其他地方拷贝一份~/.bashrc文件。

数据流重定向

当执行一个指令的时候,指令可能会从文件读入数据,经过处理之后,将数据输出到屏幕上,输出到屏幕上的数据有可能是正确数据,也有可能是错误的数据。这里就要引入3个概念:

  • 标准输入(stdin) 代码是0,符号使用<或者<<
  • 标准输出(stdout)代码是1,符号使用>或者>>
  • 标准错误输出(stderr) 代码是2,符号使用2>或者2>>

标准输入

标准输入符号可以用来代替键盘输入,比如我们使用cat > filename创建一个文件的时候,通常需要输入数据需要键盘输入:

[root@VM_16_15_centos ~]# cat > file
aaa
aaa
^C
[root@VM_16_15_centos ~]# cat file 
aaa
aaa

同时需要使用ctrl + d来离开编辑。如果我希望以某个文件为输入源的时候可以这样使用

[root@VM_16_15_centos ~]# cat > file < ~/.bashrc
[root@VM_16_15_centos ~]# cat file 
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

此时~/bashrc文件就使用标准输入符号让它作为输入源,关于<<的使用可以参考下面:

[root@VM_16_15_centos ~]# cat > file << end
> aa
> bb
> end

使用<<可以在后面加入一个’结束符号’,然后在输入的时候,碰到’结束符号’就会退出编辑(省略了ctrl + d操作)

标准输出和标准错误输出

标准输出和默认情况下是输出到屏幕的。我们可以通过重定向符号将输出到文件。其中他们的符号如下:

  • 1> 以覆盖的方式将标准输出流输出到指定的文件或者设备上,1可以省略
  • 1>> 以追加的方式将标准输出流输出到指定的文件或者设备上,1可以省略
  • 2> 以覆盖的方式将标准错误输出流输出到指定的文件或者设备上
  • 2>> 以追加的方式将标准错误输出流输出到指定的文件或者设备上

ll命令输出结果输出到文件file中:

[root@VM_16_15_centos ~]# ll / > file
[root@VM_16_15_centos ~]# cat file 
total 72
lrwxrwxrwx.   1 root root     7 Jan  9 18:19 bin -> usr/bin
dr-xr-xr-x.   5 root root  4096 Mar  8 15:46 boot
drwxr-xr-x    2 root root  4096 Mar  8 15:45 data
drwxr-xr-x   19 root root  3000 Mar 31 14:20 dev
drwxr-xr-x.  92 root root 12288 Apr 27 11:54 etc
drwxr-xr-x.   3 root root  4096 Mar 31 14:20 home
lrwxrwxrwx.   1 root root     7 Jan  9 18:19 lib -> usr/lib
lrwxrwxrwx.   1 root root     9 Jan  9 18:19 lib64 -> usr/lib64
drwx------.   2 root root 16384 Jan  9 18:18 lost+found
drwxr-xr-x.   2 root root  4096 Nov  5  2016 media
drwxr-xr-x.   2 root root  4096 Nov  5  2016 mnt
drwxr-xr-x.   3 root root  4096 Jan  9 18:23 opt
dr-xr-xr-x  117 root root     0 Mar 31 14:20 proc
drwxr-xr-x    5 root root  4096 May  9 17:58 root
drwxr-xr-x   26 root root   940 Apr 14 18:26 run
lrwxrwxrwx.   1 root root     8 Jan  9 18:19 sbin -> usr/sbin
drwxr-xr-x.   2 root root  4096 Nov  5  2016 srv
dr-xr-xr-x   13 root root     0 Mar 31 14:20 sys
drwxrwxrwt.   9 root root  4096 May  9 18:08 tmp
drwxr-xr-x.  13 root root  4096 Jan  9 18:19 usr
drwxr-xr-x.  20 root root  4096 Apr 19 18:54 var

ll命令的标准输出结果输出到right文件,错误信息输出到error文件

[root@VM_16_15_centos ~]# ll /root /root1 >right 2>error
[root@VM_16_15_centos ~]# cat right 
/root:
total 8
-rw-r--r-- 1 root root   52 May  9 18:32 error
-rw-r--r-- 1 root root 1102 May  9 18:29 file
-rw-r--r-- 1 root root    0 May  9 18:32 right
[root@VM_16_15_centos ~]# cat error 
ls: cannot access /root1: No such file or directory

垃圾桶黑洞设备

在Linux系统中,如果我们想将某些信息忽略掉,可以把输出重定向到/dev/null设备中。就是说所有输出到/dev/null设备的信息都不会保留。

比如,将ll命令的标准输出结果丢弃,可以执行以下命令:

 ll /root >/dev/null

假如需要将一个命令的标准输出和标准错误输出都输出到某个文件可以这样写:

ll /root /root1 > file 2>&1

上述命令可以这样理解,&1可以理解为1>,2>&1即表示标准错误输出输出到标准输出的地方。

为什么不用ll /root /root1 >file 2>file这样的方式呢,这样的方式虽然可以将标准输出和标准错误输出输出到file文件中,但是这两股数据交叉写入会导致顺序错误,所以正确的语法应该是2>&1这样。

管线

管线使用|符号,管线的作用在于将一个命令的标准输出结果传递到下一个命令的输入中,例如需要将/etc/目录的文件分页查询:

ll /etc/ | less

通过管线将/etc/的文件列表作为less的输入

使用管线有以下两点需要注意:

  • 管线命令仅仅会处理标准输出流,对于标准错误输出不做处理
  • 管线命令后面接的命令必须是可以接受数据的命令

下面列出一些管线相关的命令:

cut 命令

cut的主要用途在于将同一行里面的数据进行分解。比如根据某个字符切割字符。

参数有

  • d :后面接分隔字符。与 -f 一起使用;
  • f :依据-d的分隔字符将一段讯息分区成为数段,用-f取出第几段的意思;
  • c :以字符 (characters) 的单位取出固定字符区间;

grep 命令

grep命令的作用是分析一行数据,如果当中有所需的信息,则把该行取出来,并且支持正则表达式。其中参数有:

  • a 将binary文件以text文件的方式搜索数据
  • c 计算找到匹配字符的次数
  • i 忽略大小小
  • n 输出行号
  • v :反向选择,亦即显示出没有 ‘搜寻字串’ 内容的那一行
  • --color=auto :可以将找到的关键字部分加上颜色的显示

sort 命令

sore命令可以对数据进行排序。具有以下参数:

  • f 忽略大小写
  • b 忽略前面的空白字符
  • M 以月份名字方式来排序
  • n 使用纯数字进行排序
  • r 反向排序
  • u 相同的数据仅仅显示一次
  • t 分割符号
  • k 以哪个字段进行排序的意思

下面列出一些用法:

对个人账号进行排序输出:

# 默认情况下是按字母排序
cat /etc/passwd | sord

对账号信息以:分割,并且使用第三列作为排序列

cat /etc/passwd/ | sort -t ':' -k 3

uniq命令

这个命令是对数据重复提供过滤功能。

wc

这个指令用于计算文件中的字、字符、或者行数

列出/etc/man.conf文件的行数/字数/字符数

cat /etc/man.conf | wc

双向重定向

前面所说的数据重导向只能把数据存到文件或者设备中,但是如果需要在数据处理的过程中,也想看到屏幕输出怎么办?

可以使用tee命令,tee命令可以在数据处理的过程中,将数据保存为文件,并且数据会继续流向下一个命令。

例如,将/root目录结果输出到teefile中并且屏幕也显示结果

ll /root/ | tee -a teefile

总结

本篇文件粗略对Linux中的shell知识进行记录,同时主要记录了bash shell的一些相关特性,文章整理得不是很好,作为学习笔记,勿喷。

以上是关于Linux的Shell相关知识简要描述几种主流的shell及特点!!!的主要内容,如果未能解决你的问题,请参考以下文章

nginx相关知识

运维相关知识

linux shell脚本相关知识

Shell-- 基础知识

Linux Shell系列教程之(十六) Shell输入输出重定向

Linux 基础知识 | shell知识