ksh 学习

你说的应该是AIX的自动补全命令功能。AIX默认是使用 KSH,而KSH默认是不开启自动补全功能的。但你可以使用如下方法 

方法一: 

set -o vi  

历史命令功能(esc -,esc +)或者 

上滚一条命令是ESC+k 下滚一条命令是ESC+j   

自动补全文件名(esc \)。 

方法二:

 set -o emacs  

历史命令功能(ctrl-n,ctrl-p)

自动补全文件名(按两次esc)。

 或者 安装BASH也可以

--

AIX默认安装ksh,对于习惯了bash的人来说,不能tab自动补全,不能翻上/下,感觉使用起来很不方便,在ksh中不能直接实现这些功能,可以使用另外的方法来完成
一.安装bash程序,使用起来就和bash一样


二.ksh中通过其他方法完成
翻上/下条功能
1、在主目录中 vi .profile
2、添加一行:export EDITOR=vi
3、保存.profile,重新登陆;或者source ~/.profile
现在如果要使用翻上/下条功能,只需要按下esc键,然后使用j/k翻上/下即可;如果要退回到输入功能,直接输入i,然后输入即可.其实所有操作就是和vi中的操作一样.


自动补全功能
使用esc+\


---

Korn Shell

1.语法

特殊的文件

/etc/profile  在登录时首先自动执行。

$HOME/.profile  在登录时第二个自动执行。

$ENV  在创建一个新的KShell时指定要读的一个文件。

文件名元字符

*  匹配有零或零个以上字符的字符串

?  匹配任何单个字符

[abc…]  匹配括号内任何一个字符,也可用连字符指定一个范围(例如,a-z,A-Z,0-9)

[!abc…]  匹配任何不包括在括号内的字符

 

?(pattern)  匹配模式的零个或一个实例

*(pattern)  匹配指定模式的零个或多个实例

+(pattern)  匹配指定模式的一个或多个实例

@(pattern)  只匹配指定模式的一个实例

!(pattern)  匹配任何不匹配模式的字符串

\n  匹配与(…)中的第n个子模式匹配的文本。

~  当前用户的主目录

~name  用户name的主目录

 

这个模式pattern可能是由分隔符“|”或“&”分隔的模式的序列,

例:pr !(*.o|core) | lp

引用

;  命令分隔符

&  后台执行

( )  命令分组

|  管道

<> &  重定向符号

* ? [ ] ~ + - @ !  文件名元字符

““  中间的字符会逐字引用,除了`` 替换命令和$ 替换变量.

‘’  中间的所有字符都会逐字引用

\  在其后的字符会按其原来的意义逐字采用.如在””中使用 \”,\`,\$

   \a 警告,\b退格,\f 换页,\n 换行,\r 回车,\ 制表符,\v 垂直制表符,

\nnn 八进制值,\xnn 十六进制值,\’ 单引号,\” 双引号,\\ 反斜线,

``  命令的替换

$  变量的替换

命令形式

Cmd &  在后台执行

Cmd1;cmd2  命令序列,依次执行

{cmd1;cmd2;}  将命令做为一组来执行

(cmd1;cmd2)  在子shell中,将命令做为一组执行

Cmd1|cmd2  管道;将cmd1的输出作为cmd2的输入

Cmd1 `cmd2`  命令替换;用cmd2的输出作为cmd1的参数

Cmd1$(cmd2)  命令替换,可以嵌套

Cmd$((expression))  运算替换。用表达式结果作为参数

Cmd1&&cmd2  逻辑与。如果cmd1成功才执行cmd2

Cmd1||cmd2  逻辑或。如果cmd1成功则不会执行cmd2

重定向形式

文件描述符:

0         标准输入  stdin  默认为键盘

1         标准输出  stdout

2         标准错误  stderr

 

Cmd > file  将cmd的结果输出到file(覆盖)

Cmd >> file  将cmd的结果输出到file(追加)

Cmd < file  从file中获取cmd 的输入

Cmd << text  将shell脚本的内容(直到遇见一个和text一样的标记为止)作为cmd的输入

Cmd <> file  在标准输入上打开文件以便读写

 

Cmd >&n  将输出发送到文件描述符n。ll >&1

Cmd m>&n 将本来输出的m中的内容转发到n中。Ll 3>&2

Cmd >&-  关闭标准输出

Cmd <&n 获取输入

Cmd m<&n

Cmd <&- 关闭标准输入

在文件描述符和一个重定向符号间不允许有空格。

 

Cmd 2>file  将标准错误发到file中

Cmd > file 2>&1  将标准错误和标准输出都发到file

Cmd > f1 2>f2  将标准输出发到f1,标准错误发到f2

Cmd | tee files  将输出发送到标准输出和files中

Cmd 2>&1 | tee files  将输出和错误同时发到标准输出和files中

2.变量

变量替换

下列表达式中不允许使用空格。冒号是可选的,如果用冒号那么变量必须是非空的并设置了初始值。

Var=value…  将变量var 设为value

${var}  使用变量var的值;如果变量和其后面的文本是分开的则可以不加大括号。

${var:-value}  如果变量var已设置则使用它,否则使用值value

${var:=value}  如果变量var已设置则使用它,否则使用值value并将value赋给变量var

${var:+value}  如果变量var已设置则使用value,否则什么也不使用

 

例:echo ${u-$d};echo ${tmp-`date`}如果没设tmp,则执行date;

内置变量

$#  命令行参数的个数

$? 上一条命令执行后返回的值

$ 当前进程的进程号(PID), 通常用于在shell脚本中创建临时文件的名称

$0 第一个参数即命令名

$n 命令行上的第n个参数

$* 将命令行上所有参数作为一个字符串

$@ 命令行上所有参数,但每个参数都被引号引起来

 

LINENO  脚本或函数内正在执行的命令的行号

OLDPWD 前一个工作目录(由CD设置)

PPID  当前SHELL的父进程的进程号

PWD   当前工作目录(由CD设置)

RANDOM[=n] 每次引用时产生一个随机数,如果给定n则以整数n开始

SECONDS 这个整型变量的值是指从这个shell会话启动算起所过去的秒数。但它更有用的是用脚本中的计时。

例:start=$SECONDS

    read answer

    finish=$SECONDS

TMOUT   如果设置了该变量,则在没有输入的情况下经过TMOUT变量所指定的秒数后,shell退出。值为0时无效。

CDPATH

允许用户使用简单文件名作为CD的参数,从而快速改变目录。设置方法与PATH类似,通常在启动文件中设置。如果CD的参数是一个绝对路径,则不会查询CDPATH.

例:CDPATH=:/u1/nr:/u1/progs:

    export CDPATH

    cd nr

    就会进到nr中去。

    注意:变量必须大写,定义后必须导出.

数组

Kshell支持一维数组,最多支持1024个元素。第一个元素为0。

Set –A name value0 value1 …

声明数组,指定的值就成为name的元素。

 

${name[i]} i为0至1023的值,可以是表达式。返回数组元素i

${name} 返回数组元素0

${name[*]},${name[@]} 返回所有元素

下标[*]和[@]都可以提取整个数组的内容。但当它们在引号中使用时其行为是不同的。使用@可生成一个数组,这个数组是原始数组的副本,而使用*,则生成的仅仅是具有单一元素的数组(或者是一个普通变量)。

例:set -A a "${names[*]}"

    set -A b "${names[@]}" 

    set|head -5

    a[0]='alex helen jenny scott'

    b[0]=alex

    b[1]=helen

    b[2]=jenny

    b[3]=scott

${#name[*]} 返回数组元素个数

运算符

Kshell使用C语言中的运算符。

+ 加;- 减;! 逻辑非;~ 按进制取反;* 乘;/ 除;% 求余;<< 左移;>> 右移;<= 小于等于;>= 大于等于;< 小于;

> 大于;== 相等;!= 不等;&& 逻辑与;|| 逻辑或;

3.内置命令

#   注释后面的一行

 

Break [n]  从for while select until循环中退出或从n次循环中退出

 

Case value in

     Pattern1) cmds1;;

     Pattern2) cmds2;;

     …

     …

Esac

类似于select case.例:

Case $1 in

   No|yea) response=1

break;;

   -[tT]) table=TRUE;;

   *)  echo “unknown option”;exit 1;;

Esac

 

Continue [n]  在for while select until循环中跳过余下的命令,继续下一次循环(或跳过n次循环)

 

Eval args  args是一行包含shell变量的代码.eval首先进行变量扩展,并且运行由此产生的命令。在shell变量包括了重定向符号,别名或其他变量时是有用的。

例:

For option

Do

   Case “$option” in

   Save) out=’ > $newfile’;;

   Show) out=’ | more’;;

Esac

Done

Eval sort $file $out

 

Exit [n]  退出脚本,退出状态为n.

 

Export [name=[value]…]

定义全局变量,让其它shell脚本也可以使用。无参数时输出当前定义的全局变量。

 

For x [in list]

Do

   Commands

Done

使变量x(在可选的值列表中)执行commands,省略时假定为”$@”位置参数

例:

For item in `cat program_list`

Do

   Grep –c “$item.[co]” chap*

Done

 

Function name{commands;}  定义一个函数

 

If condition1

Then commands1

[elif condition2

Then commands2]

…

…

[else commands3]

Fi

条件执行语句。

 

Let expressions  执行一个或多个表达式。表达式中的变量前不必有$.如果表达式中包含了空格或其他特殊字符,则必须引起来。

例:let “I = I + 1” 或 let i=i+1

 

Read [var1[?string]] [var2 …]  从标准输入读入一行给相应的变量,并把剩余的单词给最后一个变量。String为相应的提示信息.无参时只等待一次输入。

 

Readonly [var1[=value] var2[=value] …]  设置只读变量,无参时显示所有只读变量

 

Return [n]  用于一个函数里面返回状态

 

repeat word

do

    commands

done

指定一个命令序列执行的次数。

例:

repeat 3

do

echo "bye"

done

 

Select x [in list]

Do

   Commands

Done

显示一列按list中顺序编号的菜单项。让用户键入行号选择或按return重新显示。

例:

Ps3=”select thd item number:”

Select event in format page view exit

Do

   Case “event” in

      Format) nroff $file | lp;;

      Page) pr $file | lp;;

      View) more $file;;

      Exit) exit 0;;

      *)    echo “invalid selection”;;

   Esac

Done

输出为:

1.     format

2.     page

3.     view

4.     exit

select the item number:

 

set [options arg1 arg2 …]  无参时输出所有已知变量的值。

 

Shift [n]  交换位置参数(如将$2变为$1).如果给出n,则向左移动n个位置。通常用于在while循环中迭代命令行参数。N可以是一个整数表达式。

 

Sleep [n]  睡眠n秒钟

 

Test condition 或[ condition ]  判断条件,为真返回0,否则返回非0.

文件:

-a filename         如果该文件存在而为真

-d filename         如果该文件存在且为一个目录,则为真

-f filename         如果该文件存在且为一个常规文件,则为真

-L filename         如果该文件存在且为一个符号链接,为真

-r filename         如果该文件存在且用户对其有读取权限,真

-s filename         如果该文件存在且包含信息(大于0字节),真

-w filename         如果该文件存在且对其有写入权,真

-x filename         如果该文件存在且对其有执行权,真

File1 -nt file2     如果file1存在且在file2后修改则值为真(指修改时间)

File1 -ot file2     如果file1存在且在file2前修改则值为真(指修改时间)

字符串:

string          如果string不为空字符串则值为真

-n string       如果string字符长度大于0则值为真

-z string       如果string字符长度等于0则值为真

string1=sting2      如果string1等于string2则值为真

string1!=string2        如果string1不等于string2则值为真

string2可以是通配符模式。

整数比较:

-gt 大于;-ge 大于或等于;-eq 等于;-ne 不等于; -le 小于或等于; -lt 小于

组合:

! condition                         如果condition为假则为真

condition1 –a condition2           如果两个条件都为真则为真           

condition1 –o condition2           如果两个条件有一个为真则为真

 

trap [[commands] signals]  如果接收到任何的信号signals则执行命令commands.如果完全忽略commands则会重新设置由默认行为处理指定的信号。

例:

Trap “” 2 ;忽略信号2(中断,通常是ctrl+c)

Trap 2 ;恢复中断2

Trap “rm –f $tmp;exit” 0 1 2 15 ;当shell程序退出,用户退出,按ctrl+c或执行kill时删除$tmp.

 

Typeset [options] [var [var]…]设置变量属性

-u 将变量值中所有字母全部转换成大写

-l 将变量值中所有字母全部转换成小写

-i 将变量值设为整数类型.-ix x为相应的进制,表示时为x#变量值,可用于进制转换。

    例:typeset -i2 vv  vv=2    echo $vv    2#10

    typeset -i 相当于integer

-L width 在width宽度之内左对齐

-R width 在width宽度之内右对齐,前面空位用空格填充

-Z width 在width宽度之内右对齐,变量如果是数字,则前面空位用零填充

如果忽略width,将使用赋给这个变量的第一个值的宽度。

-x 设置一个变量全局。typeset -x 相当于 export

-r 设置一个变量具有只读属性,在设置的同时或之前,要先给这些变量赋值。

例:typeset -r  PATH FPATH=/usr/local/funcs

typeset -r 相当于 readonly

不带参数的typeset可以列出变量和变量的属性。查看指定的变量属性可用type|grep day

使用带有某一选项的typeset来看看哪一个变量具有特定的属性:typeset -z

 

Unset var  删除一个变量,将它置为空

 

Until condition

Do

   Commands

Done

执行命令command直到满足条件condition.

 

While condition

Do

   Commands

Done

如果满足条件condition则执行commands


--

熟悉Linux的朋友肯定都知道bash,它是Linux默认的命令行解释程序,熟悉Solaris的也应该知道csh,但是csh用起来比较费劲,于是乎产生了Korn Shell (http://www.kornshell.com),ksh综合了csh的强

大功能和bash的易用性,作为一名忠实的Linuxer,你不得不把这一强大的工具牢牢掌握!

关于shell的用法及shell编程方面的资料很多,但是专门讲解ksh的似乎挺少的,强子在此也结合几篇E

文加上一些自己的实践尽最大努力给大家讲解一下ksh,望对你能起到一定的作用,文末附上E文地址。

1. 准备工作
首先请确保ksh程序已经安装在/bin/目录下,强子前几天装Fedora7却没有发现ksh被安装,如果没有则

直接上ksh官方网站上去下一个,然后重命名成ksh并拷贝到/bin目录下。
跟大多数脚本解释程序一样,可以选择交互式或者批处理运行,如果是交互式则直接在bash提示符下输入#ksh,然后便进入ksh交互模式,如果是批处理,则:
先得建立一个ksh脚本文件:#vi myscript.ksh
然后在文件里添加脚本代码,Esc+:+wq保存,然后给予可执行权限: #chmod 777 myscript.ksh
最后直接运行便可:#./myscript.ksh 或者 #ksh ./myscript.ksh,如果需要参数,则直接在运行命令

后面输入:#ksh ./myscript.ksh arg1 arg2 arg3 ...
当然这些参数可以直接在程序体里面使用$1, $2, $3来调用,特别地:$0始终表示脚本文件名,因为它

其实才是真正的第一个参数(ksh命令后的第一个参数始终是脚本文件名)
注:为了确保批处理文件100%是被ksh解释的,最好在每个批处理的第一行加上
#!/bin/ksh (该行表示用ksh来解释下面的程序体,它是备注的一种特殊方式#!)

2. 变量
如何定义变量:myval = "hello world"
调用:echo $myval 则输出: hello world
如果是要执行数字运算,则我们必须显式声明变量类型,如:
integer val1=1
integer val2=2
integer val3=$val1+$val2
print $val3
该段程序如果不显式指明类型,则输出会是1+2而不是3
备注:通用的备注方法:# my comment
换行:\n
注意:ksh区分大小定,所有Linux的程序好像都区分大小写,这点强子并未确认

3. 流程控制
if...else...fi语句
if ((ANIMAL=="cat")) then
print "Good"
else
print "Bad"
fi
判断条件:
== Equal
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
!= Not equal to

case...in...esac语句(条件判断中可使用通配符)
echo input yes or no
read answer
case $answer in
yes|Yes|y)
echo got a positive answer;;
no)
echo got a 'no';;
q*|Q*)
exit;;
*)
;;
esac

while...do...done语句
keeplooping=1;
while [[ $keeplooping -eq 1 ]] ; do
read quitnow
if [[ "$quitnow" = "yes" ]] ; then
keeplooping=0
fi
if [[ "$quitnow" = "q" ]] ; then
break;
fi
done

util...do...done...语句
until [[ $stopnow -eq 1 ]] ; do
echo just run this once
stopnow=1;
echo we should not be here again.
done

for...do...done语句
list="one two three"
for var in $list ; do
echo $var
list="nolist"
done

4. 数组
定义数组:
array[1]="one"
array[2]="two"
array[3]="three"
three=3
调用数组:
print ${array[1]}
print ${array[2]}
print ${array[3]}
print ${array[three]}

5. 一些内置的常量

PWD - 当前目录
RANDOM - 产生一个随机数
$$ - 输出当前进程号
PPID - 你进程ID 
$1 to $9 - 参数
$? - 退出代码
$REPLY - 数字菜单的选择项

6. 函数
printmessage() {
echo "Hello, this is the printmessage function"
}

printmessage

内置的函数:
read varname -- 从终端读取标准输入并赋值给varname
set $varname -- 为参数设定值,如果调用set $val="first second third",则$1="first"
eval -- 直接执行命令如:eval 'print hello'则直接执行命令print hello
文本位置,颜色调整 -- 用法:
tput init
tput clear
tput cup 3 2
print -n "Here is a clean screen, with these words near the top"
endline=`tput cols`
tput cup $(($endline - 2))
print "and now, back to you"
sleep 2
构建自己的数字菜单选择项:
select word in one two three exit; do
echo word is $word
echo reply is $REPLY
if [[ "$word" = "exit" ]] ; then
break;
fi
done
运行这段脚本,将输出并等待用户作出选择
1) one
2) two
3) three
4) exit
#?

7. 在Ksh里面调用其它Linux系统工具
如cut, join, comm, fmt, grep, egrep, sed, awk
强子现在正在研究awk,一个文本分析处理工具,很强大,稍后附上研究心得

8. exit和return的区别
exit会退出整个程序体,而return则只是退出当前函数体而非程序体,并有返回值。


--

ksh的基本使用知识

公司主机默认shell都是ksh,所以经常要用到,补习一下。

shell 的历史

UNIX shell 至今存在的时间已超过 35 年,它现在仍然在发展壮大!它创始于 1971 年,这一年 AT&T 贝尔实验室的 Ken Thompson 创建了第一个 UNIX shell,它具有贴切的名称 Thompson shell。虽然 Thompson shell 缺少人们日常使用的 UNIX 所具备的一些重要内置功能,如管道 (|)、编写 shell 脚本的能力和 if 条件语句,但是该 shell 的基础功能(如数据重定向)仍存在于现今使用的 shell 中。

后来,在 1997 年,Thompson shell 被 Bourne shell(即 sh)所取代。Bourne shell 是由 AT&T 贝尔实验室的 Stephen Bourne 创建的,它成为 UNIX 第 7 版 (V7) 的缺省 shell。Bourne shell 使 UNIX 的发展向前迈进了一大步。到这时,用户可以编写 shell 脚本,在变量中存储信息和导出信息,控制文件描述符,控制信号处理,使用 for 循环和 case 语句,以及其他大量功能。虽然 Bourne shell 创建至今已有 30 多年时间,目前它仍在大量的 UNIX 系统中广为使用,并且是当今许多 UNIX 系统的超级用户 —root— 的缺省 shell。

在过去三十年中,UNIX shell 获得了许多改进和增强。结果,出现了多种不同的 shell。图1显示了少数 UNIX shell 的家族树。虽然该图并不完整,但它显示了衍生出其他较次要 shell 的那些主要 shell。


图 1. UNIX shell 家族树
ksh 学习_第1张图片 


Korn shell

1982 年,AT&T 贝尔实验室的 David Korn 开发了 Korn shell(即 ksh)。Korn shell 与许多其他 shell 类似,向后兼容 Bourne shell (sh)。在超过 25 年的发展历程中,它已进化为强健、稳定和非常可靠的 shell。IBM 在 AIX 中使用 Korn shell 作为其缺省 shell。Korn shell 共有两个版本,它们均包含在 AIX 中。

第一种是 AIX 普通用户的缺省 shell,即标准 ksh shell。Korn shell 符合计算机环境的可移植操作系统接口标准 (POSIX),这是操作系统的国际标准。

AIX 提供的第二种 Korn shell 是增强 Korn shell,称为 ksh93。除标准 Korn shell 所拥有的所有强大功能外,增强 Korn shell 还包含如下功能:

  • 算术增强
  • 复合变量
  • 复合赋值
  • 关联数组
  • 变量名引用
  • 参数扩展
  • 规程函数
  • 函数环境
  • PATH 搜索规则
  • shell 历史记录
  • 其他内置命令

有关 ksh93 增强功能以及 ksh 与 ksh93 之间差异的完整列表,请参阅参考资料。

使用 ksh 设置命令行环境

在介绍如何使用 ksh 编辑命令行之前,必须设置您的环境。根据您的喜好来设置 Korn shell 相当简单:登录到 ksh 下时,使用带有 -o 开关的 set 命令来查看您的当前设置:

# set -o

Current option settings are:
allexport off
bgnice on
emacs off
errexit off
gmacs off
ignoreeof on
interactive on
keyword off
markdirs off
monitor on
noexec off
noclobber off
noglob off
nolog off
notify off
nounset off
privileged off
restricted off
trackall off
verbose off
vi off
viraw on
xtrace off 

下面简单介绍各项设置。(您也可以通过运行 man set 找到这些说明。)

  • allexport:自动导出所有定义的后续变量。
  • bgnice:在后台以更低的优先级运行所有进程。
  • emacs:编辑输入的命令行文本时,使用 emacs 风格的行内编辑器。
  • errexit:如果某个命令产生非 0(零)的退出状态并且设置了 ERR 陷阱,则执行 ERR 陷阱并退出。
  • gmacs:编辑输入的命令行文本时,使用 gmacs 风格的行内编辑器。
  • ignoreeof :忽略文件结束字符,并且不退出 shell。如果用户想要退出,则必须键入 exit 命令或按 11 次 Ctrl-D。
  • keyword :此选项将命令的所有参数放入环境中,而不仅仅放入命令之前的参数,使用 set 命令可以查看这些参数。
  • markdirs:在来自文件名替换的所有目录的末尾添加一个正斜杠 (/)。
  • monitor:将所有后台进程作为独立进程运行,并在进程结束时向 stdout 输出一行信息以通知用户。
  • noexec:不执行命令。仅检查语法错误。

    注意:此参数在交互式 shell 中无效。

  • noclobber :当输出重定向到现有文件时,此标记可阻止截断这些文件。然而,启用此选项后,如果使用大于号加管道符号 (>|),则仍然会发生截断。
  • noglob:禁用文件名替换。
  • nolog:如果使用此选项,则函数定义不会存储在历史文件中。
  • nounset:如果执行替换,则所有未设置参数都作为错误返回。
  • restricted :运行受限制的 shell。用户无法执行下列操作:更改目录;更改 SHELL、ENV 或 PATH 变量;执行在文件名中包含正斜杠 (/) 的命令;或重定向输出。
  • trackall:每个命令在最初运行时都作为被跟踪的别名。
  • verbose:当 shell 读取输入行时,向 stdout 显示所有这些行。
  • vi:编辑输入的命令行文本时,使用 vi 风格的行内编辑器。
  • viraw:键入字符时,将每个字符处理成在 vi 编辑器下输入的原样。
  • xtrace:执行命令时,向 stdout 显示所有命令和参数。

若要开启内置命令集选项,请使用 -o 开关。相反,如果改变主意,可以使用 +o 开关关闭这些选项。

本文将重点讲述的主要选项是行内编辑器开关。根据个人喜好不同,人们往往偏爱 vi、emacs 或 gmacs 文件编辑器中的某一个。Korn shell 包含所有这三种编辑器。然而,我将重点介绍 vi 行内编辑器。将行内编辑器选项设置为 vi 十分简单。只需在用于查看所有当前设置的命令后加上选项 vi:

# set -o vi 

大功告成!若要验证该设置,可以再次查看您的当前设置:

# set -o

Current option settings are:
allexport off
bgnice on
emacs off
errexit off
gmacs off
ignoreeof on
interactive on
keyword off
markdirs off
monitor on
noexec off
noclobber off
noglob off
nolog off
notify off
nounset off
privileged off
restricted off
trackall off
verbose off
vi on
viraw on
xtrace off 

使用 Korn shell vi 行内编辑器

既然已将您的 shell 配置为使用 vi 行内编辑器,现在应该开始进行测试了。

在命令行上修改文本

现在,当您在命令行上键入时,将其视为处于 vi 编辑器中的插入模式。如果出错或者需要向要执行的命令添加一些内容,只需按 Esc 键退出插入模式并切换回命令模式。

例如,您当前所在的工作目录包含如下文件:

# ls
fileA fileAA fileAAA fileAB fileABA fileABB fileB fileBAA fileBB fileBBB 

您希望查找以 fileAA 开头的文件并删除它们,于是输入以下命令:

# find . -name "fileAB*" -exec rm {} \; 

在执行您输入的行之前,您发现自己犯了一个错误,意外地将 fileAA 误输入为 fileAB。不必担心。只需退出插入模式并切换到命令模式,将光标移动到错误字符并进行替换,所有这些操作都使用 vi 命令完成。下面详细说明命令序列,此时仍然处于行内编辑器的插入模式:

  1. 按 Esc 切换到命令模式。
  2. 使用 vi 风格的移动命令向左移动光标,以突出显示字符串“fileAB*”中的 B。(H 键可向左移动光标。)

    注意:如果您习惯于在 vi 中使用箭头键,那么明智的做法是了解键盘上用于移动光标的实际字母键,因为不同类型的终端上的箭头键不一定能产生预想中的结果:

    • h:向左
    • l:向右
    • k:向上
    • j:向下
  3. 使用 vi 风格的“替换单个字符”命令将 B 替换为 A(即单击 R,然后键入 A)。

经过检查确认输入无误后,按 Enter 键执行命令:

# find . -name "fileAA*" -exec rm {} \;
# ls
fileA fileAB fileABA fileABB fileB fileBAA fileBB fileBBB 

文件名完成

Korn shell 中 vi 行内编辑器的另一个十分有用的操作是文件名完成。执行命令时,经常会遇到这样一种情况,您用作 stdin、stdout 或 stderr 参数的文件将被写入到某个文件中。文件名可能很长,也可能有多个文件具有类似的文件名,或者您就是无法记起完整的文件名。这时就会用到文件名完成功能。在 键入文件名时,如果完成了一部分,那么只需先按 Esc 键,再按反斜杠 (\)键。这样做省时省力!

例如,我要查看 AIX 上的 /etc/filesystems 文件,但我忘记了完整文件名。我知道它位于 /etc 下,并且该文件以 file 开头,仅此而已。我只需键入 view /etc/file 并按 Esc-\,哇!ksh 已经为您完成了这行内容。现在命令行显示为 view /etc/filesystems

对于目录结构也可以执行同样的操作,因为它们实际上也可算作文件名。

查看和修改命令历史记录

在您的 UNIX 系统上监视进程或执行其他一些功能时,您需要多次反复键入相同的命令。为了避免反复重新输入的麻烦,Korn shell 提供了内置的命令历史记录供您查看。如果您也将行内编辑器设为 vi,ksh 将允许您提取用户所执行命令的历史记录(有时仅限该会话,具体取决于您的系统配置),并按照您在命令行中输入的其他文本修改命令。

如果您在变量 HISTFILE 中定义了一个文件名,ksh 允许用户从其历史记录中提取和修改命令,或仅仅再次执行原始命令。例如,以下是示例 $HISTFILE 显示的最后 10 个命令:

# tail -10 $HISTFILE
ls
cd ~cormany/testdir/dirA
./fileA 1>fileA.out 2>fileA.errors
pwd
ps –fu cormany
df –k .
ps –fu cormany
find . –name “fileA.out” –ls
find . –name “fileA.errors” –ls
tail -10 $HISTFILE 

在命令行中,只需按 Esc 键即可进入 vi 行内编辑器的命令模式,然后按 K 键提取上次执行的命令。由于您仍处于命令模式,您可以继续按 K 键向上移动所执行命令的历史记录,或按 J 键向下移动列表。

若要帮助简化命令模式下的光标移动,当您在命令提示符处按 Esc 键时,请想象您加载的 $HISTFILE 为 vi 中的普通文件。在 vi 编辑器中,K 键向上移动一行,而 J 键向下移动一行。如果按 Esc-J 键并使用示例 $HISTFILE,想象正在编辑 $HISTFILE,并且光标开始位于文件底部。该行将显示 tail -10 $HISTFILE。如果再次按 J 键,正在编辑的 $HISTFILE 将向上移动一行,显示为 find . -name "fileA.errors" –ls

图2提供了小型的“备忘单”,将常规 vi 命令模式光标移动与 ksh vi 行内编辑器命令模式移动进行比较。


图 2. vi 命令模式备忘单 
ksh 学习_第2张图片 


命令行与 shell 脚本

有时会用到 shell 脚本,其他一些时间则要用到命令行。如果需要定期执行某项任务,或者任务非常复杂、需要进行数据处理,同时不需要用户反复键入各种命令,则适合使用 shell 脚本。有时,某些任务只需要执行一次并且相对简单,则使用命令行可以很好地完成这类任务。

例如,假设存在下列字典列表:

# ls
fileA.tar.gz fileAA.tar.gz fileB.tar.gz fileBB.tar.gz 

如果只需要解压缩文件,并使用 bzip2 重新压缩,然后将它们传送到 ATC-AIX2 上,那么与其键入 shell 脚本,不如使用命令行。可以将 shell 脚本视为一次输入多个命令行条目,因为从某种意义上来说,这就是实际情况。在命令行上键入命令时,就像将它们输入到脚本中,然后执行脚本。

您希望遍历目录中以 gz 结尾的文件,解压这些文件,然后使用 bzip2 重新压缩它们,再对这些文件使用 scp 命令,将它们复制到目标 ATC-AIX 服务器上。循环在命令行中的工作效果与在脚本中同样出色。当开始 loop…if 条件语句、case switch 语句,或其他代码块语句时,您正在运行的 ksh 只会将光标移动到下一行,但提示符将更改为 $PS2。当代码块完成时,将执行代码块并使用户返回 $PS1 提示符。

也就是说:

  • $PS1 提示符:等待下一个命令
  • $PS1 提示符:代码块开始
  • $PS2 提示符:代码块继续
  • $PS2 提示符:代码块继续
  • $PS2 提示符:代码块结束
  • 代码块执行
  • $PS1 提示符:等待下一个命令

变量 PS2 的缺省值为 >。返回前一个解压缩后重新压缩的功能,您只需在 ksh 命令行中键入以下内容:

# for _FNAME in 'ls -1 *.gz'
> do
> gzip -d ${_FNAME}
> bzip2 ${_FNAME%*.gz}
> scp ${_FNAME%*.gz}.bz2 cormany@ATC-AIX2:/home/cormany
> done 

完成代码块(也就是说,使用 done 结束循环)后按 Enter 键,将开始执行循环。在命令行上键入的循环将搜索当前工作目录下以 .gz 结尾的所有文件,将这些文件解压缩,然后使用 bzip2 重新压缩它们,最后将它们复制到 ATC-AIX2 上的 /home/cormany 目录中。就是如此简单。

from: http://www.ibm.com/developerworks/cn/aix/library/au-speakingunix_commandline/index.html?ca=drs-cn-08

--End--




http://bbs.chinaunix.net/thread-1749811-1-1.html

http://www.linuxdiyf.com/viewarticle.php?id=78579


你可能感兴趣的:(AIX)