-
Oracle 9i 在Linux 下的安装
2008-09-02 14:51:17
Oracle 9i 在Linux 下的安装
Oracle9i 2000 年 10 月在 Oracle Open World 上发布,为 Oracle 数据库、应用服务器和开发工具引进了许多新功能。Oracle9i是业界第一个完整、简单的用于互联网的新一代智能化的、协作各种应用的软件基础架构。Oracle9i 实际上是指 Oracle9i Database, Oracle9i Application Server 和Oracle9i Developer Suite的完整集成。随着软件逐渐开始转变为一种托管服务( hosted services),具有internet上的高伸缩性能的、智能化的、和可靠的Oracle9i 将成为高质量的电子商务服务实现的关键软件。
本文将介绍OracleDatabase 9i在Linux下的安装过程,如果你是有过安装Oracle的经验本安装过程可以权当快速安装手册;如果你以前从未在Linux下安装过Oracle数据库,那我们就从这篇文章开始熟悉oracle的安装过程。系统要求:
以下的系统要求适用于典型的Oracle安装和创建简单数据库的方式。内存:
安装Oralce 9i软件至少需要512M内存,用以下命令可以查看机子的内存大小:
grep MemTotal /proc/meminfo
MemTotal: 900252 kB
900252kB就是你系统的内存大小。交换区:
交换区的大小一般要求是内存的两倍,至少要求达到400M以上,当然是越大越好,用以下的命令可以查看系统交换区的大小:
/sbin/swapon -s
Filename Type Size Used Priority
/dev/sda6 partition 105221 686976 -1其中105221就是系统交换区的大小。
光驱:
如果你使用光盘安装Oracle9i则你的机子上需要8速以上的CDROM,如果你是下载了oracle9i的包文件,则不需要使用的CDROM。硬盘空间:
安装Oracle9i数据库至少要有2.5GB以上的剩余空间。临时硬盘空间:
Oracle安装程序在安装过程中需要400M以上的临时硬盘空间,建议使用/tmp文件夹作为零时文件夹,如果/tmp文件没有足够的硬盘,可以新创建一个文件夹作为安装的临时目录,之后设置环境变量TEMP和TMPDIR指向相应的位置,例如:
使用bash
mkdir /home/temp
TEMP=/home/temp ; export TEMP
TMPDIR=/home/temp ; export TMPDIR使用csh
mkdir /home/temp
setenv TEMP /home/temp
setenv TMPDIR /home/temp操作系统:
Oracle公司官方公布的资料指出Oracle 9i只在安装SuSuSe 7.1, 内核 2.4.4 和glibc2.2的系统上测试通过,经过本人的测试,Oracle在Linux Mandrake release 8.0,内核2.4.3-20和glibc-2.2.2的版本上也可以顺利安装,本文将以Linux Mandrake8.0为例介绍Oracle9i的安装过程。虚拟x-windows软件:
这个软件不是必要的!所谓虚拟x-windows软件指的是可在远程终端允许服务器x-windows的虚拟软件,现在流行的x-windows软件有exceed、x-win32等软件,如果你嫌在控制台安装oracle系统麻烦,可以使用虚拟x-windows软件在远程终端在图形界面下安装oralce9i,本文将以x-win32 5.0为例介绍用虚拟x-windows安装oracle9i的过程。
JDK
如果你要安装Oracle HTTP Server还需要用到blackdown的JDK1.3.1,请到以下地址下载ftp://ftp.progsoc.uts.edu.au/pub/Linux/java/JDK-1.3.0/i386/rc1/j2sdk-1.3.0-RC1-linux-i386.tar.bz2
配置内核参数
oracle9i使用Linux的共享内存、交换区等资源进行工作,如果你的内核参数设置不能满足oracle的要求,那在安装oracel9i或使用过程就会频频出现问题,因此配置系统内核的参数就显得尤为重要和关键了。内核参数的配置一般在/proc文件夹下配置:
1. 以root用户允许以下命令;
2. 进入目录/proc/sys/kernel;
3. 用cat命令或more命令查看semaphore当前参数的值:
cat sem
命令运行后将会出现如下的结果:
250 32000 32 128
其中, 250 是参数SEMMSL的值,32000是参数SEMMNS的值, 32是参数SEMOPM的值,而128则是参数SEMMNI的值。
4. 用以下的命令可以对上述参数进行修改
echo SEMMSL_value SEMMNS_value SEMOPM_value SEMMNI_value > sem
其中SEMMSL_value、SEMMNS_value、SEMOPM_value、SEMMNI_value分别用相应的值进行替换,并且这些值的顺序不能调换5. 设置共享内存大小,共享内存大小一般设为物理内存的一半,在这里我们假设物理内存为512M则共享内存的值4294967295以此类推,如果你的物理内存是1G则这里的值则是8589934590:
echo 4294967295 > shmmax
添加用户
Oracle在安装和使用中需要用特定用户(非root用户),按照oracle的标准说明是需要添加三个专门用户和用户组,为了简便大家的安装和使用我们把oracle的安装和使用归到一个特定用户来完成。
首先创建oracle用户组,我们架设这个用户组命名为dba:
以root用户登陆系统;
运行groupadd dba命令添加dba用户组;添加oracle用户:
以root用户登陆系统;
运行useradd –g dba –p password –d /oracle –s /bin/bash oracle
运行后系统创建了一个属于dba用户组的用户oracle,密码为password,主目录为/oracle使用bash这个用户将作为系统的安装和使用指定用户,因此要妥善保存好!
创建安装点(mount point)
oracle9i的典型安装需要至少两个安装点:一个安装基本的运行程序,要求至少要有850M的硬盘空间;一个为存放数据库,至少要求有450M的硬盘空间。为了简化安装我们可以把运行程序和数据库装在同一个安装点下。
在你的文件系统上找到有足够空间的分区,在分区下创建文件夹,我们假设这个文件夹为/oracle。
配置系统环境变量
很多网友安装oracle失败都是因为环境变量没有配置正确,环境变量的配置直接影响到以后oracle9i的安装和配置,在配置的时候要尤为小心!
配置x-windows变量
确认oracle9i在安装过程中是否使用本地x-windows安装还是远程虚拟x-windows安装,如果需要远程x-windows安装,则需要配置DISPLAY变量,这个变量用于告诉系统屏幕的图形将输出到什么位置,默认情况下是本机,如果你使用虚拟x-windows进行安装,则在这里指明远程终端的显示情况,比如你远程终端的IP地址是xxx.xxx.xxx.xxx则DISPLAY的变量应设为“xxx.xxx.xxx.xxx:0”后面的“:0”表示该终端的第一个显示器。
确定安装临时目录
前面我们提到过oracle9i的安装需要一个临时的可写空间,我们在这里把/tmp作为临时的可写目录。如果你不是使用/tmp作为临时可写目录则需要配置相应的值TMPDIR=/path。
配置oracle的环境变量下面提供一个例子可以供大家参照使用
export DISPLAY="192.9.200.24:0.0"
export BASH_ENV=$HOME/.bashrc
ORACLE_HOME=/oracle/product/9.0.1; export ORACLE_HOME
ORACLE_SID=oracle; export ORACLE_SID
ORACLE_TERM=xterm; export ORACLE_TERM
TNS_ADMIN=/home/oracle/config/9.0.1; export TNS_ADMIN
NLS_LANG=american_america.ZHS16GBK; export NLS_LANG
ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data; export ORA_NLS33
LD_LIBRARY_PATH=$ORACLE_HOME/lib;export LD_LIBRARY_PATH
PATH=$PATH:/bin:/usr/bin:/usr/sbin:/etc:/opt/bin:
/usr/ccs/bin:/usr/openwin
PATH=$PATH:/opt/local/bin:/opt/NSCPnav/bin:$ORACLE_HOME/bin
PATH=$PATH:/usr/local/samba/bin:/usr/ucb:
export PATH
CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:
$ORACLE_HOME/rdbms/jlib
CLASSPATH=$CLASSPATH:$ORACLE_HOME/network/jlib
TMPDIR=/tmp;export TMPDIR
umask 022
其中:
ORACLE_HOME为系统软件的安装目录;
ORACLE_SID 为数据库的SID,这里可以自行设置;
NLS_LANG 为数据库的字符集,为了保证数据库能够输出输入数据库,我们需要在这里把字符集设为american_america.ZHS16GBK,其中american_america英文字符集,ZHS16GBK为中文字符集。以oracle用户登陆系统,
vi $HOME/.bash_profile
把以上环境变量的设置粘贴到文件中,确认相应的内容并修改,存盘退出。
重新登陆oracle用户
使用set|more命令查看oracle用户的环境变量是否生效
CLASSPATH=/oracle/product/9.0.1/JRE:/oracle/product/9.0.1/jlib:
/oracle/product/9.0.1/rdbms/jlib:
/oracle/product/9.0.1/network/jlib
DISPLAY=192.9.200.24:0.0
LD_LIBRARY_PATH=/oracle/product/9.0.1/lib:/lib:/usr/lib:
NLS_LANG=american_america.ZHS16GBK
ORACLE_HOME=/oracle/product/9.0.1
ORACLE_SID=oracle
ORACLE_TERM=xterm
ORA_NLS33=/oracle/product/9.0.1/ocommon/nls/admin/data
OSTYPE=linux-gnu
PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/games:
/bin:/usr/bin:/usr/sbin:/etc:/opt/bin:/usr/ccs/bin:/usr/openwin:
/opt/local/bin:/opt/NSCPnav/bin:
/oracle/product/9.0.1/bin:/usr/local/samba/bin:/usr/ucb:
TNS_ADMIN=/home/oracle/config/9.0.1
仔细检查一下以上的几项,确保都设置正确了。
安装Oralce9i
安装JDK1.3.1
把下载的j2sdk-1.3.0-RC1-linux-i386.tar.bz2文件上传到服务器的/usr/local/目录下,以root用户登陆,用bzip –d j2sdk-1.3.0-RC1-linux-i386.tar.bz2命令先把文件解成tar格式,再使用tar xvf j2sdk-1.3.0-RC1-linux-i386.tar.bz2解压出来,为了便于操作可以把文件夹名改成jdk.。
配置x-windows
oracle9i的安装几乎支持所有的x-windows,也支持远程的虚拟x-windows安装,如果你要在本机安装在控制台上以我们先前创建的oracle用户登陆(注意要先设置好环境变量,并把DISPLAY的值设为空export DISPLAY=””)运行startx命令进入x-windows。
如果需要在远程终端使用虚拟x-windows进行安装,需要在客户端先安装x-win32软件,x-win32的安装过程我们就不多介绍了,安装完成后运行x-win32命令在你的任务栏会出现一个x的标致。使用neterm等终端攻击以oracle用户登陆系统确认环境变量都已经生效并且DISPLAY变量的值为你终端机的IP地址,运行startkde命令启动x-windows,运行完毕后系统会出现一大堆的出错信息,忽略不管,过了几秒后在你的远程终端上会出现Linux的kde界面。
下载Oracle安装软件
Oracle网站(http://otn.oracle.com)现在提供Oracle9i for Linux软件下载,在下载前请仔细阅读他的Licence,这样在今后的使用中才不会有版权问题。在下载前你需要一个otn的账户,申请是免费的,只要简单回答几个问题就可以,oracle9i的安装程序共有三个文件包分别是:
Linux9i_Disk1.cpio.gz (412,092kb)
Linux9i_Disk2.cpio.gz (638,547kb)
Linux9i_Disk3.cpio.gz (82,956kb)
下载完这三个文件后,把这三个文件上传到服务器/oracle目录下,并保证这三个文件的属主是oracle用户。如果你有Oracle9i的安装CD那就可以省下大把下载时间了
安装Oracle 9i 数据库
以oracle用户登陆系统,启动本地x-windows或虚拟x-windows,打开一个控制台窗口,进入到刚才存放oracle文件的目录下,分别使用
gunzip Linux9i_Disk1.cpio.gz
cpio -idmv
gunzip Linux9i_Disk2.cpio.gz
cpio -idmv
gunzip Linux9i_Disk3.cpio.gz
cpio -idmv
命令解包,把三个文件包解压缩成三个安装文件夹分别为Disk1、Disk2、Disk3。
进入Disk1目录
cd Disk1
在控制台窗口敲入
./runInstaller &
运行后会出现一个OUI的图形界面,中间绿色的窗口就是oracle的安装图形界面了。
下面我们来进行oracle9i最基本的安装,在进入安装界面后点Next进入下一步:Source指的是包含Oracle产品信息的文件,一般情况下他会自动识别到,如果找不到可以用Browse按钮来手工指定路径。
Destination指的是9i将要安装的路径这里就是我们在环境变量里设的$ORACLE_HOME,如果这一栏里是空白的则要重新检查环境变量中各值的设定是否有误。确认正确后按Next进行下一步:这一步有三个安装选项供选择:
Oracle9i Database 9.0.1.0.0,安装oracle9i的数据库服务器版本、管理工具、网络服务以及基本的客户端软件;
Oracle9i Client 9.0.1.0.0 ,企业版的客户端软件,网络服务以及开发工具等。
Oracle9i Mangement and Integration 9.0.1.0.0,安装Management Server,管理工具Oracle的网络目录、综合服务、网络服务以及基本的客户端软件。
我们选第一项安装Oracle9i数据库服务其,接着安Next按钮;这一步是选择Oracle安装的类型,有三个类型供选择Enterprise Edition,企业版,Standstard Edition标致版,Custom自定义安装,我们选择企业版的安装,如果你对Oracle这一系列的产品比较熟悉的化可以选择Custom自定义安装,按自己的需求选择组件进行安装,确认后安Next进入到下一步;
这里可以选择一种适合你的数据库模版,一般我们选第一种通用的数据库模版,如果你需要使用数据仓库,则可以使用选择数据仓库的模版进行安装。确认后按Next进入下一步;
这一步是确认Oracle9i的SID和全局数据库的名字,SID的值我们在环境变量中已经设好了,所以这里就自动显示了,全局数据库名(Global Database Name)我们可以也指定成和SID的值相同,确认后按Next进入下一步;
前面我们提到了,数据库的字符类型在数据库超作中是很关键的,这一步就是设置数据库的字符集,前面我们设置的是NLS_LANG=american_america.ZHS16GBK,所以我们选择Simplifiled Chinese ZHS16GBK,按Next进入下一步;
因为我们在前面选择了Enterprise的版本进行安装,系统会安装Oracle Web Server,安装Oracle Web Server需要使用JDK,我们使用Browse按钮把前面安装JDK的目录指定好以便系统能在安装过程中找到需要的应用程序,确认按Next进入下一步;
进行完所有选择后,系统会给出一个安装概要,这里列举了你选择安装的组件,确认你要安装的东西都在列表内后,安Install钮进行安装,如果不需要安装其它的程序,则按Exit退出安装界面。
Oracle的安装速度视服务器的性能一般来说需要装30分钟的时间,在安装过程中可能会有对话框弹出,对话框内会有一些需要root运行的命令要求你执行,这时候另外开一个控制台窗口,su成root并运行提示框内的命令,运行完毕后按确定继续安装;
安装完数据库后系统会运行配置工具对系统进行网络和数据库的配置。配置完成后,系统会自动启动数据库,并开启Oracle Web Server。所有配置完后,按Next完成安装。
如果一切正常,OUI会出现The Installation Of Oracle9i Database Was successful.的字样,这表明你的Oracle9i数据库安装正常了,如果需要安装其它的内容按Next Install钮进行其它内容的安装,否则按Exit退出安装。
使用Oracle 9i 数据库
安装完毕后Oracle数据库会自动启动,下面我们用实际超作来说明一下Oracle 9i数据库的启动和关闭。
以oracle用户登陆数据库,开个控制台窗口;
关闭Oracle 9i 数据库
[oracle@wing /oracle]$ sqlplus " / as sysdba" //以sysdba用户登陆数据库SQL*Plus: Release 9.0.1.0.0 - Production on Wed Jul 11 15:35:31 2001
(c) Copyright 2001 Oracle Corporation. All rights reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.0.1.0.0 - Production
With the Partitioning option
JServer Release 9.0.1.0.0 - Production
运行shudown命令关闭数据库
SQL> shutdown
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>
启动Oracle 9i 数据库
[oracle@wing bin]$ sqlplus " / as sysdba"SQL*Plus: Release 9.0.1.0.0 - Production on Wed Jul 11 16:00:59 2001
(c) Copyright 2001 Oracle Corporation. All rights reserved.
Connected to an idle instance.
SQL> startup
ORACLE instance started.Total System Global Area 336356520 bytes
Fixed Size 279720 bytes
Variable Size 268435456 bytes
Database Buffers 67108864 bytes
Redo Buffers 532480 bytes
Database mounted.
Database opened.
SQL>
启动Oracle 9i监听程序
Oracle的监听程序主要是为客户端的连接提供接口
[oracle@wing bin]$ lsnrctlLSNRCTL for Linux: Version 9.0.1.0.0 - Production on 11-JUL-2001 16:12:17
Copyright (c) 1991, 2001, Oracle Corporation. All rights reserved.
Welcome to LSNRCTL, type "help" for information.
LSNRCTL> start
Starting /oracle/product/9.0.1/bin/tnslsnr: please wait...TNSLSNR for Linux: Version 9.0.1.0.0 - Production
System parameter file is /oracle/product/9.0.1/network/admin/listener.ora
Log messages written to /oracle/product/9.0.1/network/log/listener.log
Listening on: (DEscrīptION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC)))
Listening on: (DEscrīptION=(ADDRESS=(PROTOCOL=tcp)(HOST=wing)(PORT=1521)))Connecting to (DEscrīptION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 9.0.1.0.0 - Production
Start Date 11-JUL-2001 16:12:58
Uptime 0 days 0 hr. 0 min. 0 sec
Trace Level off
Security OFF
SNMP OFF
Listener Parameter File /oracle/product/9.0.1/network/admin/listener.ora
Listener Log File /oracle/product/9.0.1/network/log/listener.log
Listening Endpoints Summary...
(DEscrīptION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC)))
(DEscrīptION=(ADDRESS=(PROTOCOL=tcp)(HOST=wing)(PORT=1521)))
Services Summary...
Service "PLSExtProc" has 1 instance(s).
Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "oracle" has 1 instance(s).
Instance "oracle", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully
LSNRCTL>
关闭Oracle 9i监听程序
[oracle@wing bin]$ lsnrctlLSNRCTL for Linux: Version 9.0.1.0.0 - Production on 11-JUL-2001 16:12:17
Copyright (c) 1991, 2001, Oracle Corporation. All rights reserved.
Welcome to LSNRCTL, type "help" for information.
LSNRCTL> stop
Connecting to (DEscrīptION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC)))
The command completed successfully
LSNRCTL>关闭Oracle Web Server
cd $ORACLE_HOME/Apache/Apache/bin
./stopJServ.sh
/oracle/product/9.0.1/Apache/Apache/bin/apachectl stop: httpd stopped启动Oracle Web Server
cd $ORACLE_HOME/Apache/Apache/bin[oracle@wing bin]$ ./startJServ.sh
/oracle/product/9.0.1/Apache/Apache/bin/apachectl start: httpd started
启动Oracle Web Server后默认的端口号是7777
在客户端浏览器地址栏输入http://xxx.xx.xxx.xxx:7777/
如果浏览器出现界面表示Oracle Web Server运行正常。 -
Linux下软件的安装
2008-08-28 21:03:12
一、rpm包安装方式步骤:
1、找到相应的软件包,比如soft.version.rpm,下载到本机某个目录;
2、打开一个终端,
su -成root用户;3、cd soft.version.rpm所在的目录;
4、输入rpm -ivh soft.version.rpm
二、deb包安装方式步骤:
1、找到相应的软件包,比如soft.version.deb,下载到本机某个目录;
2、打开一个终端,su -成root用户;
3、cd soft.version.deb所在的目录;
4、输入dpkg -i soft.version.deb
三、tar.gz源代码包安装方式:
1、找到相应的软件包,比如soft.tar.gz,下载到本机某个目录;
2、打开一个终端,su -成root用户;
3、cd soft.tar.gz所在的目录;
4、tar -xzvf soft.tar.gz //一般会生成一个soft目录
5、cd soft
6、./configure
7、make
8、make install
四、tar.bz2源代码包安装方式:
1、找到相应的软件包,比如soft.tar.bz2,下载到本机某个目录;
2、打开一个终端,su -成root用户;
3、cd soft.tar.bz2所在的目录;
4、tar -xjvf soft.tar.bz2 //一般会生成一个soft目录
5、cd soft
6、./configure
7、make
8、make install
五、apt方式安装:
1、打开一个终端,
su -成root用户;
2、apt-cache search soft 注:soft是你要找的软件的名称或相关信息
3、如果2中找到了软件soft.version,则用apt-get install soft.version命令安
装软件 注:只要你可以上网,只需要用apt-cache search查找软件,用apt-get
install软件
六、bin文件安装:
如果你下载到的软件名是soft.bin,一般情况下是个可执行文件,安装方法如下:
1、打开一个终端,su -成root用户;
2、chmod +x soft.bin
3、./soft.bin //运行这个命令就可以安装软件了
七、不需要安装的软件:
有了些软件,比如lumaqq,是不需要安装的,自带jre解压缩后可直接运行。假设
下载的是lumaqq.tar.gz,使用方法如下:
1、打开一个终端,su -成root用户;
2、tar -xzvf lumaqq.tar.gz //这一步会生成一个叫LumaQQ的目录
3、cd LumaQQ
4、chmod +x lumaqq //设置lumaqq这个程序文件为可运行
5、此时就可以运行lumaqq了,用命令./lumaqq即可,但每次运行要输入全路径或
切换到刚才生成的LumaQQ目录里
6、为了保证不设置路径就可以用,你可以在/bin目录下建立一个lumaqq的链接,
用命令ln -s lumaqq /bin/ 即可,以后任何时候打开一个终端输入lumaqq就可以
启动QQ聊天软件了
7、 如果你要想lumaqq有个菜单项,使用菜单编辑工具,比如Alacarte Menu
Editor,找到上面生成的LumaQQ目录里的lumaqq设置一个菜单项就可以了,当然你
也可以直接到 /usr/share/applications目录,按照里面其它*.desktop文件的格
式生成一个自己的desktop文件即可。
其他相关文章:
Linux下安装软件的办法 http://www.linuxsky.org/doc/newbie/200708/101.html
Linux下常见文件格式的压缩、解压小结 http://www.qqread.com/linux/2006/06/y769123061.html -
Linux背后的人
2008-08-28 20:23:25
阅读提示:似乎在一夜之间,这个名字突然变得同象比尔。盖茨一样的耳熟能详。但是比尔。盖茨,哪怕身价有数不清倍的百万美金,也永远不会变成Linux Torvalds。1. Linus和Bill
似乎在一夜之间,这个名字突然变得同象比尔。盖茨一样的耳熟能详。但是比尔。盖茨,哪怕身价有数不清倍的百万美金,也永远不会变成Linux Torvalds。这位29岁的芬兰人,简单而强大的Linux操作系统的创造者,超越了盖茨的神话。也有传闻说盖茨是一个卓越的程序员,但Linus是货真价实的高手。还在大学里时他就完成了一个货真价实的操作系统。年轻时的盖茨把拷贝他自己平庸的程序的程序员同行称为“贼”,而慷慨的Linus把他的杰作与全世界共享。哪个人,哪种运动会取胜,也许会决定技术发展的未来。
两年之前,如果有谁说技术巨人和微软的亲密合作伙伴HP,会忙着保证她生产的电脑顺利运行Linux,那会是天方夜谭。但Linus采取的开发模式,邀请全世界共享和改进他的个人原创,从而引发了一场革命。怀疑论者觉得微软面对美国司法部的起诉,把Linux标为值得重视的竞争对手,只是在制造假想敌,以洗脱垄断的罪名。但微软透露的真相也许比他们想象得多。去年岁末,一份称作“万圣节文档”的微软内部白皮书泄露到媒体,它的结论也许会让盖茨睡不安寝。
Linus被不少人认为是开放源码软件(open source software)的最佳代表人物,微软对付竞争对手的传统套路恐怕对他无可奈何。“Linux和其他开放源码软件,日渐可信地证实了OSS至少同商业软件同样强壮,如果没有超越后者的话。”微软工程师Vinod Valloppillil 的白皮书这样写道:“OSS聚积,发挥Internet上千百万人集体智能的能力令人惊异。”
但“万圣节文档”没有提到的是,Linus已经证明他是众多反盖茨人物中最高明,最强有力的一个。Oracle的CEO Larry Ellison的NC攻势只是过眼烟云,Sun的CEO Scott McNealy 尽管在JAVA上取得巨大的成功,但似乎已深陷在无条件反对盖茨的泥泞之中;相比之下,Linus 始终没有偏离自己的道路。尽管他自己绝不会承认,但你可以说他是一个圆滑老练的政治家。他避免了纯粹自由软件的支持者和以盈利为目的的厂商新人之间的对峙,将Linux搞得分崩离析。他欢迎所有能增强软件可靠性和可用性的商业Linux版本和商业Linux软件,也依然不遗余力地支持那些和他一起开创局面的自由软件激进派。
难以置信的是,在这个IPO和高科技亿万富翁层出不穷的时代,Linus并不显得急于将成功兑换成现钞。他仍然开着1997年初,离开芬兰开始在美国第一份工作(也是到目前为止唯一的工作--这是在硅谷)买的那一辆Pontiac Grand Am。一年之前,当Santa Clara 的那间小公寓再也住不下Linus,他的幼儿园教师妻子和他们的两个女儿时,他们租了所看的第一间房子--就在马路对面。关于他的雇主,高度保密的 Transmeta公司的各种谣言,在硅谷甚嚣尘上,但到目前为止,Linus似乎没有什么大发一笔横财的迹象。
面对面聊天时,这位被大多数人只以名字Linus相称的人,戴着眼镜,语音轻柔,容易接近,对自己的才能和成就充满自豪,而且十分幽默。他从前是出名地逮什么吃什么,现在则对寿司情有独钟。由于编程太多,他的肚子已经有点儿凸,不过他的声音和他顽童般的笑容里远没有失去芬兰特色的那种轻快。
Linus看来是一个平民主义者,他希望打破垄断性软件定价的思想方式,也反映在他的其他口味上。比如,他不买精装书,因为他相信精装书卖不太好,所以定价一定偏贵。同样,他更喜欢好莱坞的娱乐片,而不是欧洲的高品位艺术电影。他的父亲在电台工作,他的母亲翻译报纸新闻,叔叔为芬兰电视台工作,祖父是报纸记者,所以他理解新闻媒体,而且似乎也对于自己越来越出名自得其乐。
2. 叛逆,叛逆
问:你是否认为自己是传统的,正面意义上的黑客,一个叛逆者?我觉得仅称你为”一心编程的程序员“是不够的。
答:我一般试图避免用黑客这个词。在和其他搞技术的人私下交谈时,我会称自己黑客。但同媒体接触时我只说“程序员”什么的,因为现在黑客往往是另外一个意思。
问:那么“叛逆者”这个标签如何?
答:“叛逆者”意味着你为某种事业而战,而且是在反对另一些东西。我不说自己叛逆,我说自己是有准则的。(ethical instead of rebel)叛逆的根本意义在于反对,而我觉得有自己的目的,两者的区别就是这样。我有自己的准则,我不关心别人是否也相信这些准则,我觉得这完全是个人的选择。
问:那么你如何描述你的准则和目标呢?
答:我的基本生活准则是:“己所不欲,勿施于人”,这不是仅限于基督教的思想,这是世界性的。这条准则很简单,而且在绝大多数情况下它可以告诉你该做什么。如果你举棋不定“我该干什么”,你可以自问“我会希望他(她)干什么?”马上你就知道答案了。
问:你是否相信你的工作或者你的技术中,有一定社会或政治的因素?
答:从开始就不是这样。一开始和社会完全无关,最初的动力是技术和我的个人兴趣。没有政治性是因为:政治在本质上就是要改变人的想法,我一直不希望这种事发生在我头上。
但许多其他的“开放源码”人士未必和我一个想法。其中许多是政治性的:一些人试图让另一些人接受自己的观点,我不希望自己那样做。我也会谈自己的看法,但只是在别人问我之后。
问:有许多机会你可以下海,或者决定Linux操作系统应该商业化,但你显然没有这样做,这让我很奇怪。为什么?
答:这是我个人的兴趣问题。吸引我搞Linux的一直是技术。它一开始就不是为了赚钱,即使到了可以赚钱的时候,那也不是我的本意。商业化会改变我的动机。
我很高兴有人在Linux上赚钱,那样增加了Linux的深度,也引入了新的动机和新的因素,如果不是因为商业目的那是不可能的。但我开始Linux的时候,商业化并不是我的选择。
问:许多人会认为那是一个困难的抉择。但你却处之泰然,你觉得是为什么呢?
答:也许在美国这是一个困难的抉择,但在世界的其他许多地方就未必了。美国是以金钱为中心的,每个人都重视钱,这当然也有好处。
但在芬兰就不一样了。那里的文化背景下,成功是值得赞赏的,但你也欣赏别的东西,也许更多一些。比如说我的家族就很重视学位。他们认为学习是重要的,他们并不太在乎钱。
3. Linus 2.0
问:围绕着你在Transmeta的工作有着重重的谜团,能给我点提示什么时候可以真相大白吗?
答:不行。也许明天就可以,也许得等15年。
问:是Transmeta找你还是你找Transmeta?
答:双向选择吧。我认识一个瑞典人,他在Transmeta工作。他到了赫尔辛基呆了一天和我见面,那时我说:“总算可以毕业了。”,因为那时我已经几年没有好好放松了。然后他就问我是否愿意去 Transmeta,然后我和他的老板谈。一周之后,1996年的秋天,我就坐飞机到加州来看。
问:我理解你不能透露和工作有关的事情,但是可以告诉我这份工作哪一点让你兴奋吗?
答:部分原因是那时我已经在Linux上干了6年,也希望有一些别的东西。我可不想在一根绳上吊死。我不希望Linux是我生活的全部,我希望能够找到一些本身就能激励人的东西。而且,小公司人情味比较足。还有,涉足一些世界上没有其他人涉足的领域也让人兴奋。
问:那些东西和Linux无关吧?
答:他们在内部就用Linux。我每天都用。他们也欢迎我在Linux上面的工作。一方面是因为公关效应,另一方面是因为内部也用得上。
问:但你在Linux上的工作是没有报酬的。许多人奇怪你怎么会花这么多时间在没有钱的...
答:即使是那些无法想象世界上有人做事会出于兴趣的人--那种人是挺可悲的,但也是有这样的人,我也可以向他们解释:10年之后Linux要是真的一帆风顺,我就要风得风,要雨得雨了,就象在银行存钱一样。这不是我的目的,但可以这样告诉那些除此之外就无法理解的人。
我认为自己是一个艺术家,在做自己乐意做的事情。而且我也不用活得特别惨,因为程序员的待遇并不差。
4. 时间就是一切
问:你对资本主义的看法很有趣。看来你也相信自由软件的一些观点,但也不反对为软件和服务收费。什么情况下收费更合理,什么情况下免费更合理呢?
答:收费总是合理的。但当我开始时,我无法使用商业软件,因为它们太贵了。Linux存在的部分原因就是,我不希望任何人再陷入那种境地--这就是“己所不欲,勿施于人”。但同时我也不认为收钱就有错。
我并不反对钱。钱是个有趣的概念,但你必须选择最重要的东西?Linux好就好在,如果你是一家公司而且愿意付钱买一年365天,一天24小时的服务,你也得付一大笔钱--即使在Linux上那也是昂贵的,但如果你是一个穷学生,或者在第三世界国家,也许Linux会带给你接触一些新鲜事物的机会。
问:Linux发展的速度或者Linux发展的方向曾让你始料不及吗?
答:去年的事情也是经过一定酝酿过程的。在某种程度上,当一个公司决定支持Linux后,其他这么多公司会纷纷响应,这是让人吃惊的。不过,我从来没有在家里看得合不拢嘴,除了“哇”以外就说不了别的,我的反应更象是“嗯,够酷的,真的发生了。”
问:是不是可以说Linux很好地把握了时机?
答:Linux的成功是时机、需求和市场机会的组合。比如,Linux刚刚开发时,人们没有CDROM。Linux 面世后一年,CDROM就随处可见,于是突然就有了一种高性能价格比的商业化发行Linux的可能。所以,时机确实很好。Internet也是一个大好机会。Internet流行起来之前就已经有Linux了,但网络的基础架构一旦建立,Linux确实也或多或少地从中得益。
问:我还觉得从微软那方面的事情发展来看,Linux的出现也是恰逢其时?
答:出于公关的原因,司法部的起诉变成了一个对付微软的大聚会。两年以前,没有人质疑过微软,大家认为微碜龅氖虑槭抢硭比坏摹H嗣浅绨菸⑷恚捍蠊荆晒Γ蟀炎嗣蔷醯媚蔷褪?美国梦。司法部的起诉的一个结果是,一些原先喜欢微软的人现在改主意了。
5.开发源码是民主
问:而且他们现在也知道除了微软以外还有别的选择?
答:你提到的这个事实意味着,突然之间你开始注意到有别的选择。以前人们并不寻找其他选择。现在,即使你不从Windows转到Linux,或者作其他的大改变,你还是会说:“看来微软说的东西还得想一想” 我认为这很重要。
6.开放 vs. 封闭
问:你如何对比你开发Linux的开放源码模式和微软开发Windows和Windows NT的封闭模式?
答:在Linux上,系统的使用者可以影响开发的方向。从用户无须放弃控制这个角度说,这就是民主。每个人都可以做任何的事情。当然,基本前提是你必须有足够的能力,不过那也不失为区分干活的人和不干活的人的一种好办法。而且,即使是不修改软件的人也可以提建议,作测试,等等。
我想,作为一种开发模式,开发源码是相当优越的--尤其是与传统的商业化封闭开发环境相比。问题的本质是如何激励人去创造。
但确实有许多工作怎么样也算不上有趣,一项工作如果没有趣的话,必须靠其他的激励手段。最明显的就是通过钱。从某种程度上说,在封闭的环境下更容易挣钱。封闭模式依靠的是不给其他人提供完整的信息,从而限制竞争。限制竞争对于公司是有利的。
问:你有什么比喻可以描述这两种模式的差别吗?
答:我会这样说:封闭模式是一家出版社,它掌握的是铅字而不是语言。用户有读的自由,写的自由,但出版社决定什么样的东西可以出版发行,流传于世。你可以读,也可以用手写,但如果想要对书做什么改进的话,就得自己从头开始,或者求出版社。
问:那么,开放源码模式的比喻就应该是一台打印机喽,打印机什么都不限制。
答:对,你可以有任意多台的打印机,而且打印机之间可以共享字体。
问:这是一个有趣的比喻。为什么Linux和开放源码模式如此成功,能告诉我你的看法吗?
答:Linux能走到今天这一步,其中一个原因就是,它是弱者。在某种程度上,市场的力量对Linux的开发者没有太大的意义。人们开发Linux,是因为他们感兴趣的东西得不到足够的市场份额,而且他们也没有什么董事会跟在后面,必须每个季度解释财务状况。
你改变了游戏规则,从而也改变了市场。(You also change the market by changing the rules in ways that Microsoft isn't willing to fail on)源代码公开变成了一个卖点。突然之间有了一条新的游戏规则,并非所有的人都在乎这条规则,但只要有人在乎,他会不假思索地拒绝微软。这就象两军对阵一样:你不能让敌军挑选战场,你必须掌握主动。
问:你认为Linux有可能使微软或者其他的主流厂商改变他们的战略或者战场吗?
答:某种程度上我希望会是这样。用一个我自认为贴切的比喻来解释:让我们看当前美国最大的 5家软件公司,把他们和50年代美国最大的5家汽车制造商作个比较。当时所有的汽车公司都在新功能,新附件上竞争,每年都会推出新车型。
听起来是不是很耳熟?现在每年都会有个新版本的Windows。当时汽车公司的工作是让人们注意每年的车型翻新。所以51年的凯迪拉克和52年的凯迪拉克差别很大。人们当然就会注意车型。为什么?公司就是希望人们在乎自己开的是什么车型,几几年的车型--新年的新车型会给公司赚取大量的利润。尽管前一年的车型照样工作得很好,公司还是希望卖新车型。
我和Linux就象当年的日本汽车圃煲怠H肥担飞嫌?0年代石油危机,还有其他的因素。但问题的本质是美国的汽车业并不关心质量,而是关心新的功能,还有每年的新车型。然后,日本汽车出现了,一开始他们质量虽好,名声也不见得那么大,但是渐渐地用户们明白了:“嘿,日本汽车造得就是好。它们是没有流线型尾翼(fin),但是话讲到底,我每年换车干什么?”
我相信这是一个准确的比喻。如果微软能象美国汽车工业那样,改变它的做法,我会很高兴。如果微软真能改而在质量上和Linux竞争,那就是我的胜利。
问:微软的Steve Ballmer (第二号人物)最近提到开发Windows的源代码,你对此有何看法?
答:我所有的开发工作都是在Internet上完成的,你在Internet上学会的头一件事就是光说不练靠不住。 (and the first thing you learn on the Internet is that talk is cheap.) 除非看到了结果,否则我不相信任何言辞,这对所有的东西都是一样的,包括Ballmer的说法。眼见为实嘛。 (Show me the money! )
7. Linux vs. NT
问:谈到Ballmer和他的真正用意,你觉得微软是确实害怕Linux呢,还是它只不过利用媒体炒做对付司法部的起诉?
答:我相信一开始这是微软的有意操作,特别是去年秋天Linux刚开始引起注意的时候。微软内部没有人会这样认真地看待Linux,但他们看到它可以利用,作为法庭辩护的一个依据。但他们失算了,事情的结果是引起了许多舆论界人士的兴趣:“这个Linux到底是什么东西?”
问:你认为Linux有可能比NT使用更广泛吗?
答:如果只是比较Linux和NT,我的回答是肯定的。Windows NT和Linux占有差不多的市场份额。〖编者按:根据IDG的报告,1998年底,NT的服务器市场占有率为38%,Linux 16%,其他UNIX 19%,NETWARE 23%。将来Linux会超过NT。那一天到的时候我不会太奇怪的。真正的目标是桌面系统。这不可能在一年、两年中发生,但也许会在3年,4年,5年间实现。
问:你认为两到三年内Linux会挑战微软在桌面市场的地位?
答:是三到四年。我希望那时Linux会成为非技术的电脑用户的选择之一。
问:那会对电脑工业和微软产生什么影响呢?
答:未必会到那样的地步。我只是认为,用户没有选择的市场是病态的。
问:你用病态这个词?
答:是的,是病态。你有一个非常广阔、复杂的市场,但有一家公司控制着这市场的绝大部分。不过最终垄断是维持不下去的。
在新兴的市场中,往往一个公司掌握着巨大的实力。当年的石油大王如此,当年的汽车工业如此,当年的电脑业也是如此,那时人们认为IBM是不可战胜的。 最后总会演变成五六家大公司并立的局面,那样才会稳定。所以我认为当前的市场是病态的。
8.今后5年的道路
问:你对自由软件和商业力量之间的对立有何看法?有些纯粹主义者不喜欢Redhat或者任何其他发售Linux 商业版的公司,他们认为Linux应该保持永远免费。
答:我试图避免看事情只分黑和白。我的观点是:有了Linux,你确实可以避免商业化。可以从网上下载你需要的一切,一分钱都不用付。但坦白的说,我不希望再下载所有的东西了。现在,如果有了一台新机器,我会插进一张Redhat或者Suse的光盘,然后安装,然后再加上我自己需要的其他东西。我不需要为光盘付钱,但如果有必要的话,我是乐意掏钱的。它们确实是提供了真正的服务。这就是选择。如果你看事情一定要分黑白,认为Linux就该彻底免费,那么你也是作出了自己的选择,但我觉得那样做是局限自己。
问:看来你并不担心Redhat和诸如此类的公司会操纵Linux?
答:那是因为Redhat这样的公司不会希望接管内核的开发--这个代价他们是明白的。他们会希望员工中有许多内核开发者,一旦发生问题,可以靠自己人解决。
但他们本身并不想涉足内核开发。一个象样的商业公司,总会花时间做市场调研,搞清楚客户在做些什么,可以带给用户怎样的额外功能或价值,保证产品容易安装,解决重要的细节漏洞。关键是成品--完成一个产品,还有市场运作和组织运营。(It's about finishing touches, and it's marketing and logistics. )
问:你认为5年之后,Linux会发展成什么样?
答:对我来说,最有趣的一点始终是它各种各样的用途。我对嵌入市场感兴趣,因为那里会有些别处找不到的特殊用途。从技术的角度,超级计算机总是很性感的,但是从另一方面说,它们有趣也是因为有别处没有的特殊需求。
我觉得最有趣的市场是桌面市场,因为桌面没有任何特殊化。而反过来讲,这意味着永远不会有一个十全十美的解决方案--人们要用的东西太多了。技术上,这是一个极其困难的问题,这也就是为什么我特别关注桌面。我希望在5年之内,你可以看到Linux成为桌面系统的一个选择。也许不会替代微软,但至少会成为一个真正的选择。当2004年有人去电脑商店买他的第一台电脑时,他们会停下来考虑一下,到底是要Linux,Windows还是MacOS。
问:Linux和开放源码模式看来工作得很好,是否有其他新的商业模式引起你的兴趣呢?
答:有一种让我很感兴趣,但无法让我相信,那是“Internet语言化” (internet phrasing)的商业模式,内容包括把E-加在公司的名字前头,然后把股票的市值炒上一个数量级。我觉得这很有趣,但长远来看不会成功。
问:那你认为会发生什么呢?
答:我认为传统工业会非常重视Internet。一小部分走在前列的公司会一战成名,然后发展不错;剩下的成功机会十成中可能超不过一成。也许Yahoo 会生存下来--它的名声太显赫了,单凭这名声就可以赚钱--品牌认同还是很重要的。但通过现在的商业模式他们不会赚钱,也许他们自己已经明白了。
问:最后的问题,你认为软件产品的价格走向会怎样?
答:当年PC公司和微软是通过制作廉价的软件进入软件普遍昂贵的市场的。你看这些规模小,但是富于进取心的公司--例如Borland,现在叫 Inprise,靠做编译器成名,或者微软,靠的是BASIC,他们就是这样进入市场的。令人沮丧的是,现在微软掌握掌握市场如此牢固,新一轮的涨价又开始了。Inprise当年率先推出价格低于100美金的编译器,引起了轰动,但当时的轰动已被淡忘了。我们又回到了软件价格居高不下的时候,因为又有大公司可以说:“你就该付这么多。”
我希望我们会再有一次那样的轰动。现在的经济模式允许以高价销售软件,但我相信那不会持久。这使有些人认为我是共产主义者,但我不是--我绝对相信竞争。我只是相信竞争会获胜,价格会再一次下跌。 -
Shell编程基础
2008-08-28 10:15:39
编辑人员:Michael(WangRui)
目录
基本格式
我们可以使用任意一种文字编辑器,比如nedit、kedit、emacs、vi等来编写shell脚本,它必须以如下行开始(必须放在文件的第一行):
# !/bin/sh ...
符号#!用来告诉系统执行该脚本的程序,本例使用/bin/sh。编辑结束并保存后,如果要执行该脚本,必须先使其可执行:
chmod +x filename
此后在该脚本所在目录下,输入 ./filename 即可执行该脚本。
合理使用注释
shell 脚本中以# 开始的行表示注释,直到该行的结束。我们强烈建议你在脚本中进行适当/合理的注释,这样一来,即便你在相当长时间内没有使用该脚本,也能在短时间内就明白 它的作用和工作原理。此外,还有一个很重要的原因是,在注释的帮助下,别人可以快速有效的分享你的脚本,并提出自己的意见和改进。
变量赋值和引用
Shell编程中,使用变量无需事先声明,同时变量名的命名须遵循如下规则:
- 首个字符必须为字母(a-z,A-Z)
- 中间不能有空格,可以使用下划线(_)
- 不能使用标点符号
- 不能使用bash里的关键字(可用help命令查看保留关键字)
需要给变量赋值时,可以这么写:
变量名=值
要取用一个变量的值,只需在变量名前面加一个$:
#!/bin/sh # 对变量赋值: a="hello world" # 打印变量a的值: echo "A is:" $a
挑个自己喜欢的编辑器,输入上述内容,并保存为文件first,然后执行 chmod +x first 使其可执行,最后输入 ./first 执行该脚本。其输出结果如下:
A is: hello world
有时候变量名可能会和其它文字混淆,比如:
num=2 echo "this is the $numnd"
上述脚本并不会输出"this is the 2nd"而是"this is the ";这是由于shell会去搜索变量numnd的值,而实际上这个变量此时并没有值。这时,我们可以用花括号来告诉shell要打印的是num变量:
num=2 echo "this is the ${num}nd"
其输出结果为:this is the 2nd
Shell脚本中有许多变量是系统自动设定的,我们将在用到这些变量时再作说明。除了只在脚本内有效的普通shell变量外,还有环境变量,即那些由export关键字处理过的变量。本文不讨论环境变量,因为它们一般只在登录脚本中用到。
Shell里的命令
Unix 命令
在shell脚本中可以使用任意unix命令,不过实际上最为常用的一般都是那些文件和文字操作相关的命令。下面介绍一些常用命令的语法和功能:
- echo "some text"
- 在屏幕上输出信息
- ls
- 文件列表
- wc –l file wc -w file wc -c file
- 分别计算文件的行数(line)、单词数(word)和字符数(character)
- cp sourcefile destfile
- 文件拷贝
- mv oldname newname
- 重命名文件或移动文件
- rm file
- 删除文件
- grep 'pattern' file
- 在文件内搜索字符串或和正则表达式匹配的字符串
- cut -b column file
- 将指定范围内的文件内容输出到标准输出设备(屏幕)上。比如:输出每行第5至9个字符 cut -b5-9 file.txt,注意不要和cat命令混淆,这是两个完全不同的命令
- cat file.txt
- 输出文件内容到标准输出设备(屏幕)上
- file somefile
- 取得文件somefile的文件类型
- read var
- 提示用户输入,并将输入内容赋值给变量var
- sort file.txt
- 对file.txt文件所有行进行排序
- uniq
- 只输出文件中内容不一致的行,如: sort file.txt | uniq
- expr
- 进行数学运算,如要进行2+3的运算,命令为: expr 2 "+" 3
- find
- 搜索文件,如根据文件名搜索:find . -name filename -print
- tee
- 将数据输出到标准输出设备(屏幕) 和文件,比如:somecommand | tee outfile
- basename file
- 返回不包含路径的文件名,如: basename /bin/tux 会返回 tux
- dirname file
- 返回文件所在路径,如:dirname /bin/tux 会返回 /bin
- head file
- 打印文本文件开头几行
- tail file
- 打印文本文件末尾几行
- sed
- 是一个基本的查找替换程序。可以从标准输入(如命令管道)读入文本,并将结果输出到标准输出(屏幕);该命令采用正则表达式进行搜索。不要和 shell中的通配符相混淆。比如将 ubuntu 替换为 Ubuntu :cat text.file | sed 's/ubuntu/Ubuntu/' > newtext.file
- awk
- 用来提取文本文件中的字段。缺省的字段分割符是空格,可以使用 -F 指定其它分割符。cat file.txt | awk -F, '{print $1 "," $3 }',这里我们使用 , 作为字段分割符,同时打印第一和第三个字段。如果该文件内容为 Adam Bor, 34, IndiaKerry Miller, 22, USA,则上述命令的输出为:Adam Bor, IndiaKerry Miller, USA
概念: 管道, 重定向和 backtick
尽管这些都不是系统命令,不过它们扮演着相当重要的角色。
- 管道 (|) 将一个命令的输出作为另外一个命令的输入
grep "hello" file.txt | wc -l
上述命令会在file.txt中搜索包含有”hello”的行并计算行数,这里grep命令的输出成了wc命令的输入。
- 重定向:将命令的结果输出到文件,而不是标准输出(屏幕)
> 写入文件并复盖旧文件
>> 加到文件的尾部,保留旧文件内容
- 反短斜线
反短斜线可以将一个命令的输出作为其它命令的命令行参数。
find . -mtime -1 -type f -print
上述命令可以查找过去24小时(-mtime –2则表示过去48小时)内修改过的文件。如果你想将上述命令查找到的所有文件打包,则可以使用如下脚本:
#!/bin/sh # The ticks are backticks (`) not normal quotes ('): tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`
Shell里的流程控制
if 语句
"if"表达式如果条件为真,则执行then后的部分:
if ....; then .... elif ....; then .... else .... fi
大多数情况下,可以使用测试命令来对条件进行测试,比如可以比较字符串、判断文件是否存在及是否可读等等……通常用" [ ] "来表示条件测试,注意这里的空格很重要,要确保方括号前后的空格。
- [ -f "somefile" ] :判断是否是一个文件
- [ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
- [ -n "$var" ] :判断$var变量是否有值
- [ "$a" = "$b" ] :判断$a和$b是否相等
- [ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
执行man test可以查看所有测试表达式可以比较和判断的类型。下面是一个简单的if语句:
#!/bin/sh if [ "$SHELL" = "/bin/bash" ]; then echo "your login shell is the bash (bourne again shell)" else echo "your login shell is not bash but $SHELL" fi
变量$SHELL包含有登录shell的名称,我们拿它和/bin/bash进行比较以判断当前使用的shell是否为bash。
&& 和|| 操作符
熟悉C语言的朋友可能会喜欢下面的表达式:
[ -f "/etc/shadow" ] && echo "This computer uses shadow passwords"
这里的 && 就是一个快捷操作符,如果左边的表达式为真则执行右边的语句,你也可以把它看作逻辑运算里的与操作。上述脚本表示如果/etc/shadow文件存在,则打印”This computer uses shadow passwords”。同样shell编程中还可以用或操作(||),例如:
#!/bin/sh mailfolder=/var/spool/mail/james [ -r "$mailfolder" ] || { echo "Can not read $mailfolder" ; exit 1; } echo "$mailfolder has mail from:" grep "^From " $mailfolder
该脚本首先判断mailfolder是否可读,如果可读则打印该文件中的"From" 一行。如果不可读则或操作生效,打印错误信息后脚本退出。需要注意的是,这里我们必须使用如下两个命令:
- -打印错误信息
- -退出程序
我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用;普通函数稍后再作说明。即使不用与和或操作符,我们也可以用if表达式完成任何事情,但是使用与或操作符会更便利很多。
case 语句
case表达式可以用来匹配一个给定的字符串,而不是数字(可别和C语言里的switch...case混淆)。
case ... in ...) do something here ;; esac
让我们看一个例子,file命令可以辨别出一个给定文件的文件类型,如:file lf.gz,其输出结果为:
lf.gz: gzip compressed data, deflated, original filename, last modified: Mon Aug 27 23:09:18 2001, os: Unix
我们利用这点写了一个名为smartzip的脚本,该脚本可以自动解压bzip2, gzip和zip 类型的压缩文件:
#!/bin/sh ftype=`file "$1"` case "$ftype" in "$1: Zip archive"*) unzip "$1" ;; "$1: gzip compressed"*) gunzip "$1" ;; "$1: bzip2 compressed"*) bunzip2 "$1" ;; *) error "File $1 can not be uncompressed with smartzip";; esac
你可能注意到上面使用了一个特殊变量$1,该变量包含有传递给该脚本的第一个参数值。也就是说,当我们运行:
smartzip articles.zip
$1 就是字符串 articles.zip。
select 语句
select表达式是bash的一种扩展应用,擅长于交互式场合。用户可以从一组不同的值中进行选择:
select var in ... ; do break; done .... now $var can be used ....
下面是一个简单的示例:
#!/bin/sh echo "What is your favourite OS?" select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do break done echo "You have selected $var"
该脚本的运行结果如下:
What is your favourite OS? 1) Linux 2) Gnu Hurd 3) Free BSD 4) Other #? 1 You have selected Linux
while/for 循环
在shell中,可以使用如下循环:
while ...; do .... done
只要测试表达式条件为真,则while循环将一直运行。关键字"break"用来跳出循环,而关键字”continue”则可以跳过一个循环的馀下部分,直接跳到下一次循环中。
for循环会查看一个字符串行表(字符串用空格分隔),并将其赋给一个变量:
for var in ....; do .... done
下面的示例会把A B C分别打印到屏幕上:
#!/bin/sh for var in A B C ; do echo "var is $var" done
下面是一个实用的脚本showrpm,其功能是打印一些RPM包的统计信息:
#!/bin/sh # list a content summary of a number of RPM packages # USAGE: showrpm rpmfile1 rpmfile2 ... # EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm for rpmpackage in $*; do if [ -r "$rpmpackage" ];then echo "=============== $rpmpackage ==============" rpm -qi -p $rpmpackage else echo "ERROR: cannot read file $rpmpackage" fi done
这里出现了第二个特殊变量$*,该变量包含有输入的所有命令行参数值。如果你运行showrpm openssh.rpm w3m.rpm webgrep.rpm,那么 $* 就包含有 3 个字符串,即openssh.rpm, w3m.rpm和 webgrep.rpm。
Shell里的一些特殊符号
引号
在向程序传递任何参数之前,程序会扩展通配符和变量。这里所谓的扩展是指程序会把通配符(比如*)替换成适当的文件名,把变量替换成变量值。我们可以使用引号来防止这种扩展,先来看一个例子,假设在当前目录下有两个jpg文件:mail.jpg和tux.jpg。
#!/bin/sh echo *.jpg
运行结果为:
mail.jpg tux.jpg
引号(单引号和双引号)可以防止通配符*的扩展:
#!/bin/sh echo "*.jpg" echo '*.jpg'
其运行结果为:
*.jpg *.jpg
其中单引号更严格一些,它可以防止任何变量扩展;而双引号可以防止通配符扩展但允许变量扩展:
#!/bin/sh echo $SHELL echo "$SHELL" echo '$SHELL'
运行结果为:
/bin/bash /bin/bash $SHELL
此外还有一种防止这种扩展的方法,即使用转义字符——反斜杆:\:
echo \*.jpg echo \$SHELL
输出结果为:
*.jpg $SHELL
Here documents
当要将几行文字传递给一个命令时,用here documents是一种不错的方法。对每个脚本写一段帮助性的文字是很有用的,此时如果使用here documents就不必用echo函数一行行输出。Here document以 << 开头,后面接上一个字符串,这个字符串还必须出现在here document的末尾。下面是一个例子,在该例子中,我们对多个文件进行重命名,并且使用here documents打印帮助:
#!/bin/sh # we have less than 3 arguments. Print the help text: if [ $# -lt 3 ] ; then cat << HELP ren -- renames a number of files using sed regular expressions USAGE: ren 'regexp' 'replacement' files... EXAMPLE: rename all *.HTM files in *.html: ren 'HTM$' 'html' *.HTM HELP exit 0 fi ōLD="$1" NEW="$2" # The shift command removes one argument from the list of # command line arguments. shift shift # $* contains now all the files: for file in $*; do if [ -f "$file" ] ; then newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"` if [ -f "$newfile" ]; then echo "ERROR: $newfile exists already" else echo "renaming $file to $newfile ..." mv "$file" "$newfile" fi fi done
这个示例有点复杂,我们需要多花点时间来说明一番。第一个if表达式判断输入命令行参数是否小于3个 (特殊变量$# 表示包含参数的个数) 。如果输入参数小于3个,则将帮助文字传递给cat命令,然后由cat命令将其打印在屏幕上。打印帮助文字后程序退出。如果输入参数等于或大于3个,我们就将第一个参数赋值给变量OLD,第二个参数赋值给变量NEW。下一步,我们使用shift命令将第一个和第二个参数从参数列表中删除,这样原来的第三个参数就成为参数列表$*的第一个参数。然后我们开始循环,命令行参数列表被一个接一个地被赋值给变量$file。接着我们判断该文件是否存在,如果存在则通过sed命令搜索和替换来产生新的文件名。然后将反短斜线内命令结果赋值给newfile。这样我们就达到了目的:得到了旧文件名和新文件名。然后使用 mv命令进行重命名。
Shell里的函数
如果你写过比较复杂的脚本,就会发现可能在几个地方使用了相同的代码,这时如果用上函数,会方便很多。函数的大致样子如下:
functionname() { # inside the body $1 is the first argument given to the function # $2 the second ... body }
你需要在每个脚本的开始对函数进行声明。
下面是一个名为xtitlebar的脚本,它可以改变终端窗口的名称。这里使用了一个名为help的函数,该函数在脚本中使用了两次:
#!/bin/sh # vim: set sw=4 ts=4 et: help() { cat < xtitlebar -- change the name of an xterm, gnome-terminal or kde konsole USAGE: xtitlebar [-h] "string_for_titelbar" OPTIONS: -h help text EXAMPLE: xtitlebar "cvs" HELP exit 0 } # in case of error or if -h is given we call the function help: [ -z "$1" ] && help [ "$1" = "-h" ] && help # send the escape sequence to change the xterm titelbar: echo -e "33]0;$107" #
在脚本中提供帮助是一种很好的编程习惯,可以方便其他用户(和自己)使用和理解脚本。
命令行参数
我们已经见过$* 和 $1, $2 ... $9 等特殊变量,这些特殊变量包含了用户从命令行输入的参数。迄今为止,我们仅仅了解了一些简单的命令行语法(比如一些强制性的参数和查看帮助的-h选项)。但是在编写更复杂的程序时,您可能会发现您需要更多的自定义的选项。通常的惯例是在所有可选的参数之前加一个减号,后面再加上参数值 (比如文件名)。
有好多方法可以实现对输入参数的分析,但是下面的使用case表达式的例子无疑是一个不错的方法。
#!/bin/sh help() { cat < This is a generic command line parser demo. USAGE EXAMPLE: cmdparser -l hello -f -- -somefile1 somefile2 HELP exit 0 } while [ -n "$1" ]; do case $1 in -h) help;shift 1;; # function help is called -f) opt_f=1;shift 1;; # variable opt_f is set -l) opt_l=$2;shift 2;; # -l takes an argument -> shift by 2 --) shift;break;; # end of options -*) echo "error: no such option $1. -h for help";exit 1;; *) break;; esac done echo "opt_f is $opt_f" echo "opt_l is $opt_l" echo "first arg is $1" echo "2nd arg is $2"
你可以这样运行该脚本:
cmdparser -l hello -f -- -somefile1 somefile2
返回结果如下:
opt_f is 1 opt_l is hello first arg is -somefile1 2nd arg is somefile2
这个脚本是如何工作的呢?脚本首先在所有输入命令行参数中进行循环,将输入参数与case表达式进行比较,如果匹配则设置一个变量并且移除该参数。根据unix系统的惯例,首先输入的应该是包含减号的参数。
Shell脚本示例
一般编程步骤
现在我们来讨论编写一个脚本的一般步骤。任何优秀的脚本都应该具有帮助和输入参数。写一个框架脚本(framework.sh),该脚本包含了大多数脚本需要的框架结构,是一个非常不错的主意。这样一来,当我们开始编写新脚本时,可以先执行如下命令:
cp framework.sh myscrīpt
然后再插入自己的函数。
让我们来看看如下两个示例。
二进制到十进制的转换
脚本 b2d 将二进制数 (比如 1101) 转换为相应的十进制数。这也是一个用expr命令进行数学运算的例子:
#!/bin/sh # vim: set sw=4 ts=4 et: help() { cat < b2h -- convert binary to decimal USAGE: b2h [-h] binarynum OPTIONS: -h help text EXAMPLE: b2h 111010 will return 58 HELP exit 0 } error() { # print an error and exit echo "$1" exit 1 } lastchar() { # return the last character of a string in $rval if [ -z "$1" ]; then # empty string rval="" return fi # wc puts some space behind the output this is why we need sed: numofchar=`echo -n "$1" | wc -c | sed 's/ //g' ` # now cut out the last char rval=`echo -n "$1" | cut -b $numofchar` } chop() { # remove the last character in string and return it in $rval if [ -z "$1" ]; then # empty string rval="" return fi # wc puts some space behind the output this is why we need sed: numofchar=`echo -n "$1" | wc -c | sed 's/ //g' ` if [ "$numofchar" = "1" ]; then # only one char in string rval="" return fi numofcharminus1=`expr $numofchar "-" 1` # now cut all but the last char: rval=`echo -n "$1" | cut -b 0-${numofcharminus1}` } while [ -n "$1" ]; do case $1 in -h) help;shift 1;; # function help is called --) shift;break;; # end of options -*) error "error: no such option $1. -h for help";; *) break;; esac done # The main program sum=0 weight=1 # one arg must be given: [ -z "$1" ] && help binnum="$1" binnumorig="$1" while [ -n "$binnum" ]; do lastchar "$binnum" if [ "$rval" = "1" ]; then sum=`expr "$weight" "+" "$sum"` fi # remove the last position in $binnum chop "$binnum" binnum="$rval" weight=`expr "$weight" "*" 2` done echo "binary $binnumorig is decimal $sum" #
该脚本使用的算法是利用十进制和二进制数权值 (1,2,4,8,16,..),比如二进制"10"可以这样转换成十进制:
0 * 1 + 1 * 2 = 2
为了得到单个的二进制数我们是用了lastchar 函数。该函数使用wc –c计算字符个数,然后使用cut命令取出末尾一个字符。Chop函数的功能则是移除最后一个字符。
文件循环拷贝
你可能有这样的需求并一直都这么做:将所有发出邮件保存到一个文件中。但是过了几个月之后,这个文件可能会变得很大以至于该文件的访问速度变慢;下面的脚本 rotatefile 可以解决这个问题。这个脚本可以重命名邮件保存文件(假设为outmail)为outmail.1,而原来的outmail.1就变成了 outmail.2 等等...
#!/bin/sh # vim: set sw=4 ts=4 et: ver="0.1" help() { cat < rotatefile -- rotate the file name USAGE: rotatefile [-h] filename OPTIONS: -h help text EXAMPLE: rotatefile out This will e.g rename out.2 to out.3, out.1 to out.2, out to out.1[BR] and create an empty out-file The max number is 10 version $ver HELP exit 0 } error() { echo "$1" exit 1 } while [ -n "$1" ]; do case $1 in -h) help;shift 1;; --) break;; -*) echo "error: no such option $1. -h for help";exit 1;; *) break;; esac done # input check: if [ -z "$1" ] ; then error "ERROR: you must specify a file, use -h for help" fi filen="$1" # rename any .1 , .2 etc file: for n in 9 8 7 6 5 4 3 2 1; do if [ -f "$filen.$n" ]; then p=`expr $n + 1` echo "mv $filen.$n $filen.$p" mv $filen.$n $filen.$p fi done # rename the original file: if [ -f "$filen" ]; then echo "mv $filen $filen.1" mv $filen $filen.1 fi echo touch $filen touch $filen
这个脚本是如何工作的呢?在检测到用户提供了一个文件名之后,首先进行一个9到1的循环;文件名.9重命名为文件名.10,文件名.8重命名为文件名. 9……等等。循环结束之后,把原始文件命名为文件名.1,同时创建一个和原始文件同名的空文件(touch $filen)。
脚本调试
最简单的调试方法当然是使用echo命令。你可以在任何怀疑出错的地方用echo打印变量值,这也是大部分shell程序员花费80%的时间用于调试的原因。Shell脚本的好处在于无需重新编译,而插入一个echo命令也不需要多少时间。
shell也有一个真正的调试模式,如果脚本"strangescrīpt"出错,可以使用如下命令进行调试:
sh -x strangescrīpt
上述命令会执行该脚本,同时显示所有变量的值。
shell还有一个不执行脚本只检查语法的模式,命令如下:
sh -n your_scrīpt
这个命令会返回所有语法错误。
希望你现在已经可以开始编写自己的shell脚本了,尽情享受这份乐趣吧!
-
Linux操作系统命令
2008-08-28 09:56:52
Linux的发展前景非常不错,在Linux下做程序开发逐渐走向成熟,我们应该了解(熟悉)一下Linux!
1 、单用户模式进系统
kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/按E 键
在ro前面加入single
kernel /boot/vmlinuz-2.4.18-14 single ro root=LABEL=/
回车,按B 键进入系统。
注意:freebsd 下再多加一个命令 mount -a
2 、解压文件
tar.bz 2文件的解压 #tar jxvf *.tar.bz 2
tar.gz文件的解压 #tar xzpf *.tar.gz
rpm 文件的解压 #rpm -ivh *.rpm
3 、激活ssh 服务
/etc/rc.d/init.d/sshd start
service sshd start
ubuntu开启ssh 服务
studo apt-get install ssh
$sudo passwd root
4 、关闭防火墙
/etc/rc.d/init.d/iptables stop
Linux 防火墙的关闭和开启
1 )重启后生效
开启: chkconfig iptables on
关闭: chkconfig iptables off
2 )即时生效,重启后失效
开启: service iptables start
关闭: service iptables stop
需要说明的是对于Linux 下的其它服务都可以用以上命令执行开启和关闭操作。
在开启了防火墙时,做如下设置,开启相关端口,
修改/etc/sysconfig/iptables 文件,添加以下内容:
-A RH-Firewall-1-INPUT -m state ——state NEW -m tcp -p tcp ——dport80 -j ACCEPT
-A RH-Firewall-1-INPUT -m state ——state NEW -m tcp -p tcp ——dport22 -j ACCEPT
5 、查看开放的服务 netstat–tl
启动自动加载的服务 ntsys v
6 、设置网卡IP netconfig
查看网卡IP ifconfig
或者进入 /etc/sysconfig/network-scrips/ 目录下
cat ifcfg-eth0
FreeBSD 中修改网络配置: #ee /etc/rc.conf
FC4 的网卡IP修改 #vi /etc/sysconfig/network-scrīpts/ifcfg-eth0
己编译的网卡驱动的安装
#tar–zxvf e1000-6.0.54.tar.gz
#cd e1000-6.0.54/src
Make install
Inwmod e1000
#/etc/rc.d/init.d/network reload
#reboot
修改/etc/modules.conf 加一行
Alias eth0 e1000
7 、重起网卡 service network restart
查看进程: ps aux
8 、禁用图形界面 #vi inittab
将ID后面的 5改为3 就可以了
9 、加载光驱软驱 mount /mut/cdrom
Mount /mut/floppy
先用pwd 查看所在目录是否为挂载点,如果是,则无法挂载
如果要卸载则 M mount /mnt/cdrom
M mount /mnt/floppy
10、打开redhat自带的ftp 工具
# /sbin/service vsftpd start
查看安装ftp 的版本及安装情况
# rpm –qa | grep vsftpd
看谁登陆了FTP ,并杀死它的进程
Ps–xf | grep ftp 如ps–aux|grep运行程序
Kill进程号如 kill -9进程号
新建一个文件如“ # touch /etc/vsftpd.chroot_list
卸载: rpm–e packge name
安装 rpm–ivh *.rpm
卸载mysql 依次加上- -nodeps.- - (注意为了显示故中间有空隔)force它们相互依赖,不加无法卸载
Rpm –e mysql –client - -nodeps(- -force加上这个参数不行就不加)
Rem –e mysql
redhat卸载自带的mysql
#rpm–e perl–DBD –mySQL -2.1021-3 - -lodeps
#rpm–e mysql
11、使用mkswap命令建立swap分区再使用swapon命令启用swap分区
#mkswap /dev/sad7
#swapon /dev/sad7
12、改名命令 # mv
删除文件 #rm
删除文件夹 #rm–rf
13、linux 做禁ping
# vi /proc/sys/net/ip/ipv4/icmp_echo_ignore_all
将其值改为1 为禁ping改为0 为解禁ping
-
linux下apache+php+mysql
2008-08-24 17:24:42
“/etc/ssh/sshd_config”是OpenSSH的配置文件,允许设置选项改变这个daemon的运行。这个文件的每一行包含“关键词-值”的匹配,其中“关键词”是忽略大小写的。下面列出来的是最重要的关键词,用man命令查看帮助页(sshd (8))可以得到详细的列表。“/etc/ssh/sshd_config”是OpenSSH的配置文件,允许设置选项改变这个daemon的运行。这个文件的每一行包含“关键词-值”的匹配,其中“关键词”是忽略大小写的。下面列出来的是最重要的关键词,用man命令查看帮助页(sshd (8))可以得到详细的列表 -
Linux学习(远程控制跟IP地址配置)
2008-08-24 17:23:30
这次的主要课题:远程控制跟IP地址配置。ssh (putty,secure crt)linux远程管理
远程控制
开通ssh端口跟IP地址
安装linux的时候,ssh自带的也给安装上了,但并不能直接使用,还需要激活:
激活ssh:
/etc/rc.d/init.d/sshd start
service sshd start
netstat -tl激活以后,每次开机还都得重新激活。
可以在启动linux时自动启动ssh:
在文件/etc/rc2.d/S99local里面加入 /usr/sbin/sshd &
(/usr/sbin/sshd 是ssh启动的)这样每次开机以后就不用再次激活,直接就可以远程控制。
配置IP地址:
/etc/sysconfig/network-scrīpts/ifcfg-eth0里面的内容:
[root@localhost network-scrīpts]# cat ifcfg-eth0
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
TYPE=Ethernet
NETMASK=255.255.255.0
IPADDR=192.168.0.2
USERCTL=no
PEERDNS=yes
GATEWAY=192.168.0.1
配置完以后:
/etc/init.d/network reload 或 service network查看网卡信息: route -n查看物理网卡:mii-tool重启eth0: ifup eth0查看eth0信
息:ethtool eth0添加IP地址:ifconfig eth0 IP netmask 子网掩码 broadcast 广播地址
我的栏目
标题搜索
我的存档
数据统计
- 访问量: 60445
- 日志数: 74
- 图片数: 4
- 文件数: 2
- 建立时间: 2008-07-19
- 更新时间: 2011-10-09