ssh远程中让进程在后台可靠运行的多种方法

简介:想让进程在断开连接后依然保持运行?如果该进程已经开始运行了该如何补救?

如果有大量这类需求如何简化操作? 我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败。如何让命令提交后不受本地关闭终端窗口/网络断开连接的干扰呢?下面举了一些例子, 您可以针对不同的场景选择不同的方式来处理这个问题。

1. nohup

我们知道,当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。因此,我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。

nohup 的使用是十分方便的,只需在要处理的命令前加上 nohup 即可,标准输出和标准错误缺省会被重定向到 nohup.out 文件中。一般我们可在结尾加上”&”来将命令同时放入后台运行,也可用”>filename 2>&1″来更改缺省的重定向文件名。

nohup 示例

[root@pvcent107 ~]# nohup pingwww.ibm.com &
[1] 3059
nohup: appending output to `nohup.out'
[root@pvcent107 ~]# ps -ef |grep 3059
root      3059   984  0 21:06 pts/3    00:00:00 ping www.ibm.com
root      3067   984  0 21:06 pts/3    00:00:00 grep 3059
[root@pvcent107 ~]#

2. setsid

nohup 无疑能通过忽略 HUP 信号来使我们的进程避免中途被中断,但如果我们换个角度思考,如果我们的进程不属于接受 HUP 信号的终端的子进程,那么自然也就不会受到 HUP 信号的影响了。setsid 就能帮助我们做到这一点。

setsid 示例

[root@pvcent107 ~]# setsid ping www.ibm.com
[root@pvcent107 ~]# ps -ef | grep www.ibm.com
root     31094     1  0 07:28 ?        00:00:00 ping www.ibm.com
root     31102 29217  0 07:29 pts/4    00:00:00 grep www.ibm.com
[root@pvcent107 ~]#

值得注意的是,上例中我们的进程 ID(PID)为31094,而它的父 ID(PPID)为1(即为 init 进程 ID),并不是当前终端的进程 ID。

3. & subshell

这里还有一个关于 subshell 的小技巧。我们知道,将一个或多个命名包含在“()”中就能让这些命令在子 shell 中运行中,从而扩展出很多有趣的功能,我们现在要讨论的就是其中之一。 当我们将”&”也放入“()”内之后,我们就会发现所提交的作业并不在作业列表中,也就是说,是无法通过jobs来查看的。让我们来看看为什么这样就能躲过 HUP 信号的影响吧。

subshell 示例

[root@pvcent107 ~]# (ping www.ibm.com &)
[root@pvcent107 ~]# ps -ef | grep www.ibm.com
root     16270     1  0 14:13 pts/4    00:00:00 ping www.ibm.com
root     16278 15362  0 14:13 pts/4    00:00:00 grep www.ibm.com
[root@pvcent107 ~]#

从上例中可以看出,新提交的进程的父 ID(PPID)为1(init 进程的 PID),并不是当前终端的进程 ID。因此并不属于当前终端的子进程,从而也就不会受到当前终端的 HUP 信号的影响了。

4. disown

这时想加 nohup 或者 setsid 已经为时已晚,只能通过作业调度和 disown 来解决这个问题了。我们已经知道,如果事先在命令前加上 nohup 或者 setsid 就可以避免 HUP 信号的影响。但是如果我们未加任何处理就已经提交了命令,该如何补救才能让它避免 HUP 信号的影响呢?这时想加 nohup 或者 setsid 已经为时已晚,只能通过作业调度和 disown 来解决这个问题了。

用disown -h jobspec 来使某个作业忽略HUP信号。

用disown -ah 来使所有的作业都忽略HUP信号。

用disown -rh 来使正在运行的作业忽略HUP信号。

灵活运用 CTRL-z

在我们的日常工作中,我们可以用 CTRL-z 来将当前进程挂起到后台暂停运行,执行一些别
的操作,然后再用 fg 来将挂起的进程重新放回前台(也可用 bg 来将挂起的进程放在后台)
继续运行。这样我们就可以在一个终端内灵活切换运行多个任务,这一点在调试代码时尤为有
用。因为将代码编辑器挂起到后台再重新放回时,光标定位仍然停留在上次挂起时的位置,避
免了重新定位的麻烦。

disown 示例1(如果提交命令时已经用“&”将命令放入后台运行,则可以直接使用“disown”)

[root@pvcent107 build]# cp -r testLargeFile largeFile &
[1] 4825
[root@pvcent107 build]# jobs
[1]+  Running                 cp -i -r testLargeFile largeFile &
[root@pvcent107 build]# disown -h %1
[root@pvcent107 build]# ps -ef |grep largeFile
root      4825   968  1 09:46 pts/4    00:00:00 cp -i -r testLargeFile largeFile
root      4853   968  0 09:46 pts/4    00:00:00 grep largeFile
[root@pvcent107 build]# logout

disown 示例2(如果提交命令时未使用“&”将命令放入后台运行,可使用 CTRL-z 和“bg”将其放入后台,再使用“disown”)

[root@pvcent107 build]# cp -r testLargeFile largeFile2
[1]+  Stopped                 cp -i -r testLargeFile largeFile2
[root@pvcent107 build]# bg %1
[1]+ cp -i -r testLargeFile largeFile2 &
[root@pvcent107 build]# jobs
[1]+  Running                 cp -i -r testLargeFile largeFile2 &
[root@pvcent107 build]# disown -h %1
[root@pvcent107 build]# ps -ef |grep largeFile2
root      5790  5577  1 10:04 pts/3    00:00:00 cp -i -r testLargeFile largeFile2
root      5824  5577  0 10:05 pts/3    00:00:00 grep largeFile2
[root@pvcent107 build]#

5.screen

我们已经知道了如何让进程免受 HUP 信号的影响,但是如果有大量这种命令需要在稳定的后台里运行,如何避免对每条命令都做这样的操作呢?此时最方便的方法就是 screen 了。简单的说,screen 提供了 ANSI/VT100 的终端模拟器,使它能够在一个真实终端下运行多个全屏的伪终端。screen 的参数很多,具有很强大的功能,我们在此仅介绍其常用功能以及简要分析一下为什么使用 screen 能够避免 HUP 信号的影响。

用screen -dmS session name 来建立一个处于断开模式下的会话(并指定其会话名)。
用screen -list 来列出所有会话。
用screen -r session name 来重新连接指定会话。

screen 示例

[root@pvcent107 ~]# screen -dmS Urumchi
[root@pvcent107 ~]# screen -list
There is a screen on:
        12842.Urumchi   (Detached)
1 Socket in /tmp/screens/S-root.
[root@pvcent107 ~]# screen -r Urumchi

总结
现在几种方法已经介绍完毕,我们可以根据不同的场景来选择不同的方案。nohup/setsid 无疑是临时需要时最方便的方法,disown 能帮助我们来事后补救当前已经在运行了的作业,而 screen 则是在大批量操作时不二的选择了。

让vim不要自动添加新的注释行

vim里面有一个特性,如果你在一行注释后新加一行,vim会自动在下一行的开始位置添加注释符号。例如对于C/C++来说:

//This is a comment line
//

第二行的”//”符号就是vim自动添加的。如果是在大量编写注释,那这个功能还是比较有用的。但是,我经常从其它地方复制一些代码,然后在putty中用鼠标右键一点就相当于自动键入,如果代码中有一行注释,就会导致后面的所有代码全部自动被注释掉,相当不方便。 查了一下,有以下两种简单的解决办法:

1. 在.vimrc文件(这个文件在$HOME目录下)添加以下内容:

autocmd FileType * setlocal formatoptions-=c formatoptions-=r formatoptions-=o

这样,所有的文件都不会自动添加注释符号了。

2. 如果只是针对C/C++类型的文件想禁用这个功能,可以在.vimrc中添加以下内容:

au FileType c,cpp setlocal comments-=:// comments+=f://

 

linux分区知识与大磁盘的分区

文件系统限制:

以下信息出自:维基百科

ext3

块尺寸 最大文件尺寸 最大文件系统尺寸
1KiB 16GiB 2TiB
2KiB 256GiB 8TiB
4KiB 2TiB 16TiB
8KiB 16TiB 32TiB

ext4

最大文件尺寸 16 TiB (for 4k block filesystem)
最大卷容量 1 EiB

xfs

最大可支持的文件大小为263 = 9 x 1018 = 9 exabytes,
最大文件系统尺寸为18 exabytes。

ReiserFS

最大文件尺寸 8 TiB
最大卷容量 16 TiB

大于2T的磁盘分区方法

由于MBR分区表只支持2T磁盘,所以大于2T的磁盘必须使用GPT分区表,具体方法如下:

GPT格式的磁盘相当于原来MBR磁盘中原来保留4个partition table的4*16个字节,只留第一个16个字节,类似于扩展分区,真正的partition table在512字节之后,GPT磁盘没有四个主分区的限制。

fdisk不支持GPT,我们可以使用parted来对GPT磁盘操作。

#parted

在提示符下输入parted就会进入交互式模式

   1. parted>  
   2. parted>select sdb               假设磁盘为sdb  
   3. parted>mklabel gpt              将MBR磁盘格式化为GPT  
   4. #parted>mklabel msdos           将GPT磁盘转化为MBR磁盘  
   5. parted>mkpart primary 4096s 100 划分一个起始位置为4096扇区(4K对齐),大小为100M的主分区  
   6. parted>mkpart primary 100 200   划分一个起始位置为100M,大小为100M的主分区  
   7. #parted>mkpart primary 0 -1     将整块磁盘分成一个分区  
   8. parted>print                    打印当前分区  
   9. parted>quit                     退出

parted的更多命令:

Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) help                                                             
  align-check TYPE N                       check partition N for TYPE(min|opt) alignment
  check NUMBER                             do a simple check on the file system
  cp [FROM-DEVICE] FROM-NUMBER TO-NUMBER   copy file system to another partition
  help [COMMAND]                           print general help, or help on COMMAND
  mklabel,mktable LABEL-TYPE               create a new disklabel (partition table)
  mkfs NUMBER FS-TYPE                      make a FS-TYPE file system on partition NUMBER
  mkpart PART-TYPE [FS-TYPE] START END     make a partition
  mkpartfs PART-TYPE FS-TYPE START END     make a partition with a file system
  move NUMBER START END                    move partition NUMBER
  name NUMBER NAME                         name partition NUMBER as NAME
  print [devices|free|list,all|NUMBER]     display the partition table, available devices, free space, all found
        partitions, or a particular partition
  quit                                     exit program
  rescue START END                         rescue a lost partition near START and END
  resize NUMBER START END                  resize partition NUMBER and its file system
  rm NUMBER                                delete partition NUMBER
  select DEVICE                            choose the device to edit
  set NUMBER FLAG STATE                    change the FLAG on partition NUMBER
  toggle [NUMBER [FLAG]]                   toggle the state of FLAG on partition NUMBER
  unit UNIT                                set the default unit to UNIT
  version                                  display the version number and copyright information of GNU Parted
(parted)

在parted里边不支持对文件系统进行格式化,所以如果要使用的话,要退出parted进行格式化。

mkfs.ext3 /dev/sdx1

因为fdisk是不支持GPT磁盘,所以不要使用fdisk -l来查看X磁盘刚才分好的区,看不到的。

e2label命令修改磁盘分区的label。

 

修改linux系统默认的桌面位置

linux系统给出了Home目录下的一些文件夹,这些文件夹是中文或英文首先字母为大写。因此输入路径的时候特别不放便。直接重命名这些文件会造成一些不便,比如无法直接在桌面上新建文件和文件夹。

为了修改这些路径,修改~/.config/user-dirs.dirs即可。

vim ~/.config/user-dirs

centos 安装 Adobe Flash Player

1. Change Root User

sudo -i
## OR ##
su -

2. Install Adobe YUM Repository RPM package

## Adobe Repository 32-bit x86 ##
rpm -ivh http://linuxdownload.adobe.com/adobe-release/adobe-release-i386-1.0-1.noarch.rpm
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-adobe-linux

## Adobe Repository 64-bit x86_64 ##
rpm -ivh http://linuxdownload.adobe.com/adobe-release/adobe-release-x86_64-1.0-1.noarch.rpm
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-adobe-linux

3. Update Repositories

yum check-update

4a. Install Adobe Flash Player 11.1 on Fedora 16/15/14/13/12, CentOS 6.2/6.1/6/5.7 and Red Hat (RHEL) 6.2/6.1/6/5.7 Fedora 16/15/14/13/12, CentOS 6 and Red Hat (RHEL) 6 32-bit and 64-bit version

yum install flash-plugin nspluginwrapper alsa-plugins-pulseaudio libcurl

4b. Install Adobe Flash Player 11.1 on CentOS 5.7 and Red Hat (RHEL) 5.7 CentOS and Red Hat 32-bit and 64-bit version

yum groupinstall "Sound and Video"

yum install flash-plugin nspluginwrapper curl

5. Verify that the Flash Player Plugin is working

Open Mozilla Firefox and write about:plugins on address bar. Results 
should look like following:
Adobe Flash Player 64-bit installed on Fedora 16 64-bit (x86_64)

fstab释疑

文件/etc/fstab存放的是系统中的文件系统信息。每行中的字段都由空格或tab键分开。以下是每行的说明:

   fs_spec: 设备或远程文件系统
   fs_file: 挂载点,SWAP分区的字段则为SWAP
   fs_type: 文件系统类型
fs_options: 文件系统参数,一般选default,具体参数说明见下表
   fs_dump: 文件系统应该以多快频率进行转储,不需要转储就设置该字段为0
   fs_pass: 启动时需要被扫描的文件系统的顺序,若该文件系统无需在启动时扫描则设置
该字段为0,扫描文件系统的命令是fsck(用来检查与修正硬盘错误的指令)。

    ro: 以只读模式加载该文件系统
  sync: 不对该设备的写操作进行缓冲处理,这可以防止在非正常关机时情况下破坏文件系
统,但是却降低了计算机速度
  user: 允许普通用户加载该文件系统
 quota: 强制在该文件系统上进行磁盘定额限制
noauto: 不再使用mount -a命令(例如系统启动时)加载该文件系统

an example of fstab:

/dev/mapper/vg_hzaumycology-lv_root /                       ext4    defaults        1 1
UUID=081751dd-cd3f-4e42-8265-ca860fcb56b5 /boot                   ext4    defaults        1 2
/dev/mapper/vg_hzaumycology-lv_home /home                   ext4    defaults        1 2
/dev/mapper/vg_hzaumycology-lv_swap swap                    swap    defaults        0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
//122.205.95.76/Archive /remoteserver/Archive   cifs    username=chenlianfu,passwd=123456      0 0
//122.205.95.76/Blog    /remoteserver/Blog      cifs    username=chenlianfu,passwd=123456      0 0

How do I forcefully unmount a Linux disk partition?

It happens many times you try to unmount a disk partition or mounted CD/DVD disk and if you try to unmount device, which is accessed by other users, then you will get error umount: /xxx: device is busy.

What happens basically, is that Linux / UNIX will not allow you to unmount a device that is busy. There are many reasons for this (such as program accessing partition or open file) ,but the most important one is to prevent data loss.

1 the first method

Try the following command to find out what processes have activities on the device/partition. If your device name is /dev/sdb1, enter the following command as root user:

# lsof | grep '/dev/sda1' 
Output: vi 4453 vivek 3u BLK 8,1 8167 /dev/sda1

Above output tells that user vivek has a vi process running that is using /dev/sda1. All you have to do is stop vi process and run umount again. As soon as that program terminates its task, the device will no longer be busy and you can unmount it with the following command:

# kill 4453
# umount /dev/sda1

 2 the second method

Linux fuser command to forcefully unmount a disk partition

Suppose you have /dev/sda1 mounted on /mnt directory then you can use fuser command as follows:Type the command to unmount /mnt forcefully:

# fuser -km /mnt 

Where, 
    -k : Kill processes accessing the file. 
    -m : Name specifies a file on a mounted file system or a block 
device that is mounted. In above example you are using /mnt

 3 the third method

# umount -l /mnt

Where,
    -l : Also known as Lazy unmount. Detach the filesystem from 
the filesystem hierarchy now, and cleanup all references to the 
filesystem as soon as it is not busy anymore. This option works 
with kernel version 2.4.11+ and above only.

4 the fourth method

# umount -f /mnt

Where,

    -f: Force unmount in case of an unreachable NFS system

Caution: Using these commands or option can cause data loss for open files;      programs which access files after the file system has been unmounted will get an error.

关于amd64和ia64的理解

现在买的PC或者服务器都有64位的机器,而有时我们安装系统,不管是Windows还是Linux系统,要发挥机器的最高性能,必须也要安装64位的OS,否则,就达不到最好的性能。

比如:32位操作系统,配合32位CPU,寻址空间位2^32次方,计算出来是4294967296字节,就是4G,32位系统最大支持4G空间,如果想要32位

系统支持4G以上空间的话,就要用PAE的特殊内核,采用特殊方式访问,但是系统效率会比原生的64位系统低。当然有时有的Linux只能识别到3G多,因为据说是当初在设计上的缺陷。这里不做详解。

而64位操作系统配合64位CPU,寻址空间是2^64次方,计算出来是18446744073709551616字节,换算一下4G个G,太大了,反正是N多G,一辈子也用不完。当然这是64位系统的理论最大内存支持,实际上谁也用不了这么大内存.

等等…

因此我们要下载64的操作系统,而我们看到有64的操作系统最经常见到的有ia64/amd64,它们如何区分呢,哪些CPU是属于AMD64,哪些是属于IA64呢?

其实很多人从字面上,都以为AMD64就是针对AMD CPU的,IA64是针对INTEL CPU,其实是错的,我最初也是这样认为,其实不然:

你在市面上买的到的intel 64位 CPU都属于amd64范畴这个架构应该称为 x86_64,因此不管是AMD的64位CPU,还是INTEL的64位CPU,都是属于AMD64范畴.

而IA64指的是Intel安腾系列CPU,不是X86架构的。ia64主要用在服务器上面,而不是我们平常使用的桌面,通常这些cpu很贵,相关的内存以及硬盘同样很贵!

因此你以后你PC的CPU是64位的[有Intel,也有AMD],非安腾的CPU的话,你就下载AMD64的OS进行安装即可.

使用inode来重命名或删除文件

最近通过服务器下载了一部电影,存放在服务器的家目录下。但是电影的文件名是乱码,表现为一大堆乱码和无意义字符。无法通过文件名来对文件名进行重命名,删除和复制。面对这种情况,解决方法为:

1 首先通过命令查看该文件的inode。

#ls -ilh

 2 通过命令来对文件进行重命名或删除。

例如,我下载的电影原本名称为《龙门飞甲.rmvb》,但下载下来后名称为乱码《???ŷɼ?(?????ſ?ջ)HD??????????????.rmvb》,其inode号码为7077900。

#mv -i `find . -maxdepth 1 -inum 7077900 -print` 龙门飞甲.rmvb。
#rm -i `find . -maxdepth 1 -inum 7077900 -print`