灌溉梦想,记录脚步

Crontab实现定时任务

  Crontab是一个很方便的在unix/linux系统上定时(循环)执行某个任务的程序
  使用cron服务,用 service crond status 查看 cron服务状态,如果没有启动则 service crond start启动它,
  cron服务是一个定时执行的服务,可以通过crontab 命令添加或者编辑需要定时执行的任务:
  crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数
  crontab -l //列出某个用户cron服务的详细内容
  crontab -r //删除没个用户的cron服务
  crontab -e //编辑某个用户的cron服务
  比如说root查看自己的cron设置:crontab -u root -l 再例如,root想删除fred的cron设置:crontab -u fred -r 在编辑cron服务时,编辑的内容有一些格式和约定,输入:crontab -u root -e 进入vi编辑模式,编辑的内容一定要符合下面的格式:*/1 * * * * ls >> /tmp/ls.txt 编辑/etc/crontab文件,在末尾加上一行: 30 5 * * * root init 6 这样就将系统配置为了每天早上5点30自动重新启动。
  需要将crond设置为系统启动后自动启动的服务,可以在/etc/rc.d/rc.local 中,在末尾加上
  service crond start 如果还需要在系统启动十加载其他服务,可以继续加上其他服务的启动命令。
  比如: service mysqld start 基本用法: 1. crontab -l 列出当前的crontab任务
  2. crontab -d 删除当前的crontab任务
  3. crontab -e (solaris5.8上面是 crontab -r) 编辑一个crontab任务,ctrl_D结束
  4. crontab filename 以filename做为crontab的任务列表文件并载入
  crontab file的格式: crontab 文件中的行由 6 个字段组成,不同字段间用空格或 tab 键分隔。前 5 个字段指定命令要运行的时间
  分钟 (0-59) 小时 (0-23) 日期 (1-31) 月份 (1-12) 星期几(0-6,其中 0 代表星期日)
  第 6 个字段是一个要在适当时间执行的字符串
  例子: #MIN HOUR DAY MONTH DAYOFWEEK COMMAND #每天早上6点10分
  10 6 * * * date #每两个小时
  0 */2 * * * date (solaris 5.8似乎不支持此种写法) #晚上11点到早上8点之间每两个小时,早上8点
  0 23-7/2,8 * * * date #每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
  0 11 4 * mon-wed date #1月份日早上4点
  0 4 1 jan * date 补充:在使用crontab的时候,要特别注意的是运行脚本中能够访问到的环境变量和当前测试环境中的环境变量未必一致,一个比较保险的做法是在运行的脚本程序中自行设置环境变量(export) (1)先建一个文件crond.txt如下, 每天早上5点36分重新启动
  36 5 * * * reboot (2)上传到/opt目录
  (3)运行命令
  crontab /opt/crond.txt crontab -l 让配置文件生效:如果让配置文件生效,还得重新启动cron,切记,既然每个用户下的cron配置文件修改后。也要重新启动cron服务器。
  在Fedora 和Redhat中,我们应该用;
  [root@localhost ~]# /etc/init.d/crond restart 如果让crond 在开机时运行,应该改变其运行级别;
  [root@localhost ~]# chkconfig –levels 35 crond on service crond status 查看 cron服务状态,如果没有启动则 service crond start启动它, cron服务是一个定时执行的服务,可以通过crontab 命令添加或者编辑需要定时执行的任务
  Crontab文件的每一行由六个域(minutes、hours、day of month、month、day of week、 command)组 成,域之间用空格或Tab分开,其中:
  minutes: 分钟域,值的范围是0到59 hours: 小时域,值的范围是0到23 day of month: 日期,值的范围是1到31 month: 月份,值的范围是1到12 day of week: 星期,值的范围是0到6,星期日值为0 command: 所要运行的命令
  如果一个域是*,表明命令可以在该域所有可能的取值范围内执行。
  如果一个域是由连字符隔开的两个数字,表明命令可以在两个数字之间的范围内执行(包括两个数字 本身)。
  如果一个域是由逗号隔开的一系列值组成的,表明命令可以在这些值组成的范围内执行。
  如果日期域和星期域都有值,则这两个域都有效。
  编写一个文件,用以启动自动备份进程。
  cd /opt touch reboot.txt 在reboot.txt中添加一下内容: 0 4 * * * reboot crontab /opt/reboot.txt 用crontab -e编辑定时操作,例如加入下行命令:
  用crontab -l命令来查看
  注意:需要启动服务(添加在rc.local中) 重启crond任务
  /etc/init.d/cron restart (ubuntu下) 第一种 在Fedora或Redhat 等以RPM包管理的系统中;
  [root@localhost ~]# /etc/init.d/crond start [root@localhost ~]# /etc/init.d/crond stop [root@localhost ~]# /etc/init.d/crond restart /etc/rc.d/init.d/crond restart 命令简介
  crontab-操作每个用户的守护程序和该执行的时间表。
  部分参数说明
  crontab file [-u user]-用指定的文件替代目前的crontab。
  crontab-[-u user]-用标准输入替代目前的crontab. crontab-1[user]-列出用户目前的crontab. crontab-e[user]-编辑用户目前的crontab. crontab-d[user]-删除用户目前的crontab. crontab-c dir- 指定crontab的目录。
  crontab文件的格式:M H D m d cmd. M: 分钟(0-59)。
  H:小时(0-23)。
  D:天(1-31)。
  m: 月(1-12)。
  d: 一星期内的天(0~6,0为星期天)。
  cmd要运行的程序,程序被送入sh执行,这个shell只有USER,HOME,SHELL这三个环境变量。
  下面是一个例子文件:
  #MIN HOUR DAY MONTH DAYOFWEEK COMMAND
  #每天早上6点
  106* * * date
  #每两个小时
  0*/2* * * date
  #晚上11点到早上8点之间每两个小时,早上部点
  0 23-7/2,8* * * date
  #每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
  0 11 4* mon-wed date
  #1月份日早上4点
  0 4 1 jan* date
  范例
  lark:~>crontab-1 列出用户目前的crontab.
  #MIN HOUR DAY MONTH DAYOFWEEK COMMAND
  10 6* * * date
  0*/2* * * date
  0 23-7/2,8 * * * date

 

Robots.txt 文件示例

  robots.txt 文件对抓取网络的搜索引擎漫游器(称为漫游器)进行限制。这些漫游器是自动的,在它们访问网页前会查看是否存在限制其访问特定网页的 robots.txt 文件。如果你想保护网站上的某些内容不被搜索引擎收入的话,robots.txt 是一个简单有效的工具。这里简单介绍一下怎么使用它。
  如何放置 Robots.txt 文件
  robots.txt自身是一个文本文件。它必须位于域名的根目录中并 被命名为”robots.txt”。位于子目录中的 robots.txt 文件无效,因为漫游器只在域名的根目录中查找此文件。例如,http://www.example.com/robots.txt 是有效位置,http://www.example.com/mysite/robots.txt 则不是。
  这里举一个robots.txt的例子:
  User-agent: *
  Disallow: /cgi-bin/
  Disallow: /tmp/
  Disallow: /~name/

  使用 robots.txt 文件拦截或删除整个网站
  要从搜索引擎中删除您的网站,并防止所有漫游器在以后抓取您的网站,请将以下 robots.txt 文件放入您服务器的根目录:
  User-agent: *
  Disallow: /
  要只从 Google 中删除您的网站,并只是防止 Googlebot 将来抓取您的网站,请将以下 robots.txt 文件放入您服务器的根目录:
  User-agent: Googlebot
  Disallow: /

  每个端口都应有自己的 robots.txt 文件。尤其是您通过 http 和 https 托管内容的时候,这些协议都需要有各自的 robots.txt 文件。例如,要让 Googlebot 只为所有的 http 网页而不为 https 网页编制索引,应使用下面的 robots.txt 文件。
  对于 http 协议 (http://yourserver.com/robots.txt):
  User-agent: *
  Allow: /

  对于 https 协议 (https://yourserver.com/robots.txt):
  User-agent: *
  Disallow: /

  允许所有的漫游器访问您的网页
  User-agent: *
  Disallow:

  (另一种方法: 建立一个空的 “/robots.txt” 文件, 或者不使用robot.txt。)
  使用 robots.txt 文件拦截或删除网页
  您可以使用 robots.txt 文件来阻止 Googlebot 抓取您网站上的网页。 例如,如果您正在手动创建 robots.txt 文件以阻止 Googlebot 抓取某一特定目录下(例如,private)的所有网页,可使用以下 robots.txt 条目:
  User-agent: Googlebot
  Disallow: /private

  要阻止 Googlebot 抓取特定文件类型(例如,.gif)的所有文件,可使用以下 robots.txt 条目:
  User-agent: Googlebot
  Disallow: /*.gif$

  要阻止 Googlebot 抓取所有包含 ? 的网址(具体地说,这种网址以您的域名开头,后接任意字符串,然后是问号,而后又是任意字符串),可使用以下条目:
  User-agent: Googlebot
  Disallow: /*?

  尽管我们不抓取被 robots.txt 拦截的网页内容或为其编制索引,但如果我们在网络上的其他网页中发现这些内容,我们仍然会抓取其网址并编制索引。因此,网页网址及其他公开的信息,例如指 向该网站的链接中的定位文字,有可能会出现在 Google 搜索结果中。不过,您网页上的内容不会被抓取、编制索引和显示。
  作为网站管理员工具的一部分,Google提供了robots.txt分析工具 。它可以按照 Googlebot 读取 robots.txt 文件的相同方式读取该文件,并且可为 Google user-agents(如 Googlebot)提供结果。我们强烈建议您使用它。 在创建一个 robots.txt 文件之前,有必要考虑一下哪些内容可以被用户搜得到,而哪些则不应该被搜得到。 这样的话,通过合理地使用 robots.txt , 搜索引擎在把用户带到您网站的同时,又能保证隐私信息不被收录。

RAID 5单个硬盘损坏解决办法

设备环境为:HP-DL380-G5,用四个500G的sata盘做的raid5,在一次突然断电之后不久,有一块硬盘亮红灯,基本判断为已经掉线。咨询HP-800要求先备份数据,而后重启检查,但是服务器跑的是虚拟化,单个文件最大在128G以上,没有vcent授权无法迁移,所以800建议等于废话。
采取的办法是:关机,把坏掉的盘撤掉,换上同型号同容量的硬盘,开机,会有个提示:F1(重建raid覆盖现有信息),F2(重建raid保留现有信息),选择F1,启动,没有出现异常。

nash和initrd.img分析

  nash仅仅是作为initrd.img当中加载驱动所使用的命令解释器而已,并没有对initrd.img当中的linuxrc脚本作一个深入的了解。Redhat ES3当中的initrd.img内容如下:
  #!/bin/nash
  echo “Loading scsi_mod.o module”
  insmod /lib/scsi_mod.o
  echo “Loading sd_mod.o module”
  insmod /lib/sd_mod.o
  echo “Loading libata.o module”
  insmod /lib/libata.o
  echo “Loading ata_piix.o module”
  insmod /lib/ata_piix.o
  echo “Loading jbd.o module”
  insmod /lib/jbd.o
  echo “Loading ext3.o module”
  insmod /lib/ext3.o
  echo Mounting /proc filesystem
  mount -t proc /proc /proc
  echo Creating block devices
  mkdevices /dev
  echo Creating root device
  mkrootdev /dev/root
  echo 0x0100 > /proc/sys/kernel/real-root-dev
  echo Mounting root filesystem
  mount -o defaults –ro -t ext3 /dev/root /sysroot
  pivot_root /sysroot /sysroot/initrd
  umount /initrd/proc

  前面是加载驱动部分,而后面是什么用处,就没有深究了。而我自己用的虚拟机里通常会把驱动和文件系统支持编译到内核,也压根用不着initrd.img,所以把这个宝矿放了过去。今天几个学生在Redhat 9的基础上升级内核到2.6.19,并且是驱动、文件系统用模块方式支持,终于出了问题。该来的还是要来的,应了那句话”出来混,迟早都是要还的”。学生们把前面的硬盘驱动、文件系统驱动都替换成2.6的模块,后半部分在我的误导下删除(当然没有删除的也多半没有成功),结果死活不能进入系统,报无法挂载根文件系统的kernel panic错误。查了半天,发现所有的驱动都加载正常,即便是在linuxrc当中加入bash获得一个shell,检查设备和文件系统的状况也都是正常,可就是提示找不到根文件系统。
  开始引起我注意的是,通常在硬盘驱动和文件系统支持都完备的情况下它并没有提示说VFS的root=xxxx错误,而直接提示的”VFS: Unable to mount root fs on (0, 0)”。这意味着它并未识别在grub.conf当中传递给kernel的root=/dev/xxx参数,因为Linux的设备主设备号是不会为0的。我曾怀疑root=参数没有被接受,但却注意到”Please append a correct “root=” boot option”的提示。
  为了找出问题,我在linuxrc中用bash取得了一个shell,然后挂载proc文件系统后检查/proc/sys/kernel/real_root_dev,发现其值为0。这说明kernel得到的真实root文件系统的设备号不正确(当然有例外,注意后面的解释)。我试着把正确的设备值(例如/dev/sda2用0x802)写入,退出bash之后启动果然正常了。这说明kernel解析参数root=/dev/xxx出现了错误。
  经过核对内核代码,发现kernel确实从root=这个参数传递中获得真实的根文件系统的位置,但是这些/dev/xxx会被转换成内核可识别的设备表示形式。转换的过程中内核会试图检查传递进来的/dev/xxx设备是否存在,而这一步是kernel初始化过程中完成的。当我们把硬盘驱动编译为模块时,kernel初始化过程中硬盘尚不能被识别(要等到kernel初始化完,使用initrd.img才能加载硬盘驱动),于是真实根文件系统的设备号就不能被正确转换,使得其保留为初始值0。
  那对于使用硬盘驱动的情况下如何解决这个问题呢?那就是initrd.img后半部分的工作。在加载完硬盘驱动后,脚本会用mkrootdev生成设备/dev/root,通过man nash你会发现这个命令的作用是根据内核传递参数当中的root=来创建对应该设备的节点,节点名就是/dev/root。之后它会把这个设备挂载到/sysroot这个位置,然后用pivot_root这个根交换的命令把真正运行的根文件系统切换到/sysroot之下,而运行linuxrc的initrd的文件系统将被挂载到真正的根系统下的initrd目录。至于”echo 0x0100 > /proc/sys/kernel/real-root-dev”这个命令,看起来是告诉内核真正的文件系统是/dev/ram0,其实是利用内核判断使用/dev/ram0为根文件系统时不再mount其他设备作为根文件系统的分支,作了一个小小的技巧骗过内核。
  整个脚本的关键在于mkrootdev这个命令。它不仅能够根据root=/dev/xxx来生成对应的设备节点,还能够在碰到root=LABEL=/的情况下探测所有的硬盘分区,以便找到对应着卷标为/的分区。这也解开了我一直没弄清楚的为什么root=LABEL=xxx的参数有些环境可以用而有些却不行的谜团。这个LABEL=/的解析根本不是内核完成的,而是initrd.img当中linuxrc脚本的mkrootdev命令来完成的。脚本的第二个关键在于它负责完成了本是由内核做的挂载真实根文件系统的动作,并对当前根(即initrd使用的内存文件系统)和真实根文件系统进行根切换,又利用欺骗让内核误认为当前使用/dev/ram0作为根文件系统可以不再挂载真实的根文件系统,可谓用心良苦啊 ^_^
  当然,如果完全不用initrd.img的机制,你会发现/proc/sys/kernel/real_root_dev的值也是0。这并不是内核也弄错了,而是只有在使用initrd.img机制时,real_root_dev才反映了内核中记录的真实根文件系统的值,虽然它不一定准确。
  最后,总结一下:
  1、当硬盘驱动以模块形式提供时root=xxx传递给内核的参数可能不会直接起作用,内核在检查这个参数时可能会发现这个设备(因为没有加载驱动而)不存在,因此导致内核没有接受root=xxx的参数。
  2、在这种情况下,initrd.img机制的作用不单单是加载驱动这么简单,还肩负着把正确的真实根的设备位置告知内核的艰巨任务。不过实现的方法有两种:
  2.1 把正确的根设备号写入/proc/sys/kernel/real_root_dev,或者
  2.2 自己挂载真正的根设备,并进行根交换把根系统切换到真实的根系统上,还要阻止内核去挂载它认为的真实根系统
  对于2.2,挂载真正的根系统用nash解释器的内置命令mkrootdev完成,它可以根据传递给kernel的参数(估计读了/proc/cmdline)获得/dev/xxx的字符串,或者得到LABEL=xxx的字符串后查询各个分区的卷标来得到对应的真实根设备号。
  3、如果没有使用initrd.img的机制,/proc/sys/kernel/real_root_dev的值没有任何处理,因为它只有在调用initrd.img的时候才会被同步于内核中的操作对象。
  另外,redhat 9所带的nash解释器(版本3.4.42)在处理mkrootdev的流程上是有bug的。如果传给kernel的参数使用root=/dev/xxx的形式,那么nash会从/proc/sys/kernel/real_root_dev里获取用户想使用的真实根文件系统位置,显然这在我们上面的分析当中是0,也就是错误的;而如果参数传递是root=LABEL=/的形式,那么nash的处理走的另外一个分支,它会通过解析所有分区的卷标来查找所要的真实根文件系统,并不再查询/proc/sys/kernel/real_root_dev,这倒让我们可以得到正确的结果。bug呀bug。
  不过FC6所带的nash 5.1.19已经完全不是这个流程了,应当不存在这样的bug。

使用cpio解压initrd.img

2.6内核中的initrd.img采用cpio压缩,不再是2.4内核使用的ext2格式,无法使用mount -o loop 挂载。需要使用gunzip解压缩,然后再使用cpio解包

cp /boot/initrd-2.6.18-8.1.15.el5.img initrd.img.gz
gunzip initrd.img.gz
mkdir initrd
mv initrd.img initrd
cd initrd
cpio -ivmd < initrd.img

通过以上命令就将initrd.img解压了,现在就可以对其进行编辑,完成后使用以下命令重新压制

find . | cpio -cv > ../initrd.new.img
gzip ../initrd.new.img

再将其改名拷贝至/boot目录,重启就可以观察修改后的效果

linux通过ISCSI无盘启动

一、环境

server: HP Athlon 64bit 3500+ | (running ietd,ISC dhcp,pxelinux,tftp-hpa)

client: DELL Latitude | D610 | (running iSCSI initiator Core)

kernel ver 2.6.14.5 , both server & client machines

二、Server Tasks:

  Setup ISC DHCP
  Setup Syslinux (for PXELinux) & TFTP-HPA
  Setup TFTP-HPA
  Setup iSCSI Target (ietd enterprise target)
  • ) Update! you can skip the dhcp,syslinux,tftp steps by running this auto-configurator!
 wget http://linux-iscsi.org/iscsiboot/server-scripts/pxeserver-setup.sh

三、Client Tasks:

  Setup iSCSI initiator (iSCSI initiator Core)
  Boot time

四、Setup ISC DHCP http://ftp.isc.org/isc/dhcp/dhcp-3.0.3.tar.gz

edit /etc/dhcp/dhcpd.conf

 allow booting;
 allow bootp;
 option routers 192.168.1.6;
 option subnet-mask 255.255.255.0;
 ddns-update-style ad-hoc;
 subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.111 192.168.1.115;
 }
 group {
    next-server 192.168.1.6;
    filename "pxelinux.0";
    host laptop-eth0 {
        hardware ethernet 00:00:00:00:00:00; (replace with your mac-address)
 }

五、Setup PXELinux http://kernel.org/pub/linux/utils/boot/syslinux/syslinux-3.11.tar.gz

1) untar syslinux, make && make install

2) untar tftp-hpa, make && make install

  mkdir -p /tftproot/pxelinux.cfg
  cp pxelinux.0 /tftproot
  • ) build a kernel for your client and cp to /tftproot/
  • ) make an initrd and cp to /tftproot

edit /tftproot/pxelinux.cfg/default

  TIMEOUT 50
  PROMPT 1
  LABEL iscsiboot
  KERNEL vmlinuzLaptop
  APPEND root=/dev/ram initrd=bblinux25M
  IPAPPEND 1
  LABEL disk
  LOCALBOOT 0

六、Setup TFTP-HPA http://www.kernel.org/pub/software/network/tftp/tftp-hpa-0.41.tar.gz

  tar zxvf tftp-hpa-0.41.tar.gz
  cd tftp-hpa-0.41
  ./configure
  make
  make install
  • ) Start tftpd: /sbin/in.tftpd -l -v -s /tftproot

Setup iSCSI Target

1) download ietd

  svn export svn://svn.berlios.de/iscsitarget/trunk
  cd trunk && make KERNELSRC=/usr/src/linux && make KERNELSRC=/usr/src/linux install

2) make some test disk.

  ie: dd if=/dev/zero of=/iscsi-diska bs=4096k count=1024

3) configure your new LUN in /etc/ietd.conf

  Target laptop:diska
  Lun 0 Path=/iscsi-diska,Type=fileio
  Alias dell
  DataPDUInOrder Yes
  DataSequenceInOrder Yes

4) start ietd

  /etc/init.d/iscsi-target start

(client side installation notes)

七、Setup iSCSI initiator Core

1) download core-iscsi-tools

http://kernel.org/pub/linux/utils/storage/iscsi/core-iscsi-tools-v3.3.tar.bz2

2) download core-iscsi

http://kernel.org/pub/linux/kernel/people/nab/iscsi-initiator-core/core-iscsi-v1.6.2.5.tar.bz2

3) compile core-iscsi

  make initiator KERNEL_DIR=/usr/src/linux && make install

4) compile core-iscsi-tools

  make install

iSCSI core stack is then loadable via iscsi_initiator_mod.ko,

core tools rely upon /etc/sysconfig/initiator

  CHANNEL="0 2 eth0 192.168.55.6 3260 0"

and /etc/sysconfig/iscsi_device_maps

  DEVICE="0 0 1 diska"

八、Boot time

1) Change bios on client to pxeboot before HD

2) at the pxelinux prompt, type iscsiboot (referring to label in pxelinux.cfg/default)

after successfully booting, do something like this:

  /bin/mount / -o rw,remount
  /bin/mount -t proc none /proc
  /bin/mount -o sysfs /sys
  /sbin/ifconfig eth0 192.168.1.92 255.255.255.0
  cd /dev && /bin/mknod sdb1 b 8 17
  NAME=$(/sbin/initiator-iname)
  echo "InitiatorName=$NAME" > /etc/initiatorname.iscsi
  /etc/rc.d/init.d/initiator start
  • ) If this is a new installation, partition and create a file system, then copy minimal files to your new disk
  /bin/fdisk /dev/sdb # (create partition)
  /bin/mke2fs /dev/sdb1
  /bin/mount /dev/sdb1 /laptop:diska
  cp -dpRav /bin /sbin /dev /etc /var /lib /usr /tmp /laptop:diska
  • ) And, lastly:
  /bin/chroot /laptop:diska /bin/bash

Linux中如何查看文件的最初创建时间

  在Linux中,没有文件创建时间的概念。只有文件的访问时间、修改时间、状态改变时间。也就是说不能知道文件的创建时间。但如果文件创建后就没有修改过,修改时间=创建时间;如果文件创建后,状态就没有改变过,那么状态改变时间=创建时间;如果文件创建后,没有被读取过,那么访问时间=创建时间,这个基本不太可能。
  与文件相关的几个时间:
  1、访问时间,读一次这个文件的内容,这个时间就会更新。比如对这个文件使用more命令。ls、stat命令都不会修改文件的访问时间。
  2、修改时间,对文件内容修改一次,这个时间就会更新。比如:vi后保存文件。ls -l列出的时间就是这个时间。
  3、状态改变时间。通过chmod命令更改一次文件属性,这个时间就会更新。查看文件的详细的状态、准确的修改时间等,可以通过stat命令 文件名。
  比如: [jing@zhjh c]$ stat temp.c
  引用:
  File: ‘temp.c’
  Size: 66 Blocks: 8 IO Block: 4096 \u4e00\u822c\u6587\u4ef6
  Device: 807h/2055d Inode: 1191481 Links: 1
  Access: (0664/-rw-rw-r–) Uid: ( 500/ jing) Gid: ( 500/ jing)
  Access: 2008-03-12 20:19:45.000000000 0800
  Modify: 2008-03-12 20:19:45.000000000 0800
  Change: 2008-03-12 20:19:45.000000000 0800
  说明:Access访问时间。Modify修改时间。Change状态改变时间。可以stat *查看这个目录所有文件的状态。