大文件处理

由于系统的开发、配置,网络动态变化等各方面原因,大文件处理、下载、上传、分发往往更容易失败。

 

git 传输:

git config –global http.postBuffer 524288000

 

niginx 上传

http region: client_max_body_size 1024m;

其它:

server region:

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;

最简单git服务器


远程仓库一节中,我们讲了远程仓库实际上和本地仓库没啥不同,纯粹为了7×24小时开机并交换大家的修改。

GitHub就是一个免费托管开源代码的远程仓库。但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓库使用。

搭建Git服务器需要准备一台运行Linux的机器,强烈推荐用Ubuntu或Debian,这样,通过几条简单的apt命令就可以完成安装。

假设你已经有sudo权限的用户账号,下面,正式开始安装。

第一步,安装git

$ sudo apt-get install git

第二步,创建一个git用户,用来运行git服务:

$ sudo adduser git

第三步,创建证书登录:

收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。

第四步,初始化Git仓库:

先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:

$ sudo git init --bare sample.git

Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git

$ sudo chown -R git:git sample.git

第五步,禁用shell登录:

出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:

git:x:1001:1001:,,,:/home/git:/bin/bash

改为:

git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。

第六步,克隆远程仓库:

现在,可以通过git clone命令克隆远程仓库了,在各自的电脑上运行:

$ git clone git@server:/srv/sample.git
Cloning into 'sample'...
warning: You appear to have cloned an empty repository.

剩下的推送就简单了。

管理公钥

如果团队很小,把每个人的公钥收集起来放到服务器的/home/git/.ssh/authorized_keys文件里就是可行的。如果团队有几百号人,就没法这么玩了,这时,可以用Gitosis来管理公钥。

这里我们不介绍怎么玩Gitosis了,几百号人的团队基本都在500强了,相信找个高水平的Linux管理员问题不大。

ssh-copy-id git@server-ip

管理权限

有很多不但视源代码如生命,而且视员工为窃贼的公司,会在版本控制系统里设置一套完善的权限控制,每个人是否有读写权限会精确到每个分支甚至每个目录下。因为Git是为Linux源代码托管而开发的,所以Git也继承了开源社区的精神,不支持权限控制。不过,因为Git支持钩子(hook),所以,可以在服务器端编写一系列脚本来控制提交等操作,达到权限控制的目的。Gitolite就是这个工具。

这里我们也不介绍Gitolite了,不要把有限的生命浪费到权限斗争中。

管理权限

push已有代码到仓库中

git remote add shock git@hk.shockjiang.vip:~/sample.git
git push shock master

 


remarks, 最后推荐一款带web界面的轻量级git系统:gitea, 范例: http://git.shockjiang.vip

 

ffmpeg cmds & api

ffmpeg -help filter=transform
ffmpeg -help encoder=mjpeg
ffmpeg -help encoder=h264

截取一帧(从第一秒开始): ffmpeg -ss 1 -y -i merge8k.mp4 -f image2 -t 0.001 8k-3dv.jpg or ffmpeg -f h264 -i a.h264 -vf fps=1 -y a.jpg

crop尺寸:ffmpeg -y -i ${src}.jpg -filter:v “crop=in_w/4:in_h/3:in_w/4:0″ ${src}-2.jpg

Crop area with size 100×100 at position (12,34): crop=100:100:12:34

MP4 to MP3:  ffmpeg -y -i va.mp4 -q:a 0 -map a va.mp3

ffmpeg -stream_loop -1 -i input.mp4 -c copy -fflags +genpts output.mp4
to HLS: ffmpeg -i ${F1} -vcodec copy -acodec copy -f hls -hls_list_size 100 new/${HEAD}.m3u8

check channel number: ffprobe input.file -show_streams -select_streams a:0 | grep ‘channels=’

录制屏幕: ffmpeg -f v4l2 -r 10 -video_size 640×480 -i /dev/video0 /home/shock/t.mkv (not that v4l2 stands for video4linux2)

ffplay -f v4l2 -i /dev/video0
ffmpeg -f v4l2 -framerate 30 -video_size 840×620 -i /dev/video -c:v libx264 -r 30 -preset fast -tune zerolatency OUT

ffmpeg -f x11grab -framerate 30 -video_size 640×480 -i :0.0

WAV to M4A: ffmpeg -i SPTL007.WAV -c:a aac -strict -2 -b:a 256k -ac 4 t3.m4a

ffmpeg -f x11grab -framerate 30 -i :0.0 -c:v libx264 -r 30 -pix_fmt yuv420p -bf 0 -preset ultrafast -g 10 -b:v 3M -tune zerolatency -c:a libfdk_aac -f flv rtmp://r730.kandao.tech:1936/live/demo2
ffmpeg -i rtmp://localhost:1936/live/demo2 -c:v copy -b:v 1M -preset ultrafast -tune zerolatency -an -f flv rtmp://100015x.publish.z1.pili.qiniup.com/kandaovr/live?key=d2d0eff5-662b-47fd-b13f-bb56f54031b0

ffmpeg -i rtmp://pili-publish.live4.kandaovr.com/kandaovr4/demo?e=1471255883&token=QClzJjFYhx-NIT_vJRKf-tVzzTIPMGxhscDu890H:OmasOCdg0QPP4B_QGgYQeAxCcBU=

ffmpeg -f gdigrab -i desktop -c:v libx264 -r 30 -pix_fmt yuv420p -preset fast -tune zerolatency -c:a libfdk_aac -f flv rtmp://r730.kandao.tech:1936/live/demo2
ffmpeg -f gdigrab -framerate 30 -video_size 400×278 -i title=”Adobe Flash Player 9” -c:v libx264 -pix_fmt yuv420p -r 30 -bf 0 -g 10 -b:v 3M -preset fast -tune zerolatency -c:a libfdk_aac -f flv rtmp://r730.kandao.tech:1936/live/demo2

ffplay -tune zerolatency -i rtmp://r730.kandao.tech:1936/live/demo2
ffplay -i rtmp://100015x.live1-rtmp.z1.pili.qiniucdn.com/kandaovr/live

 

loop:

export src=a.mp4

export src=a.mp4

export dst=rmtp://xxx.xxx.xx

while :

do

ffmpeg -re -i ${src} -f flv ${dst}

done

 

ffprobe

统计总帧数

示例命令

$ ffprobe -v error -count_frames -select_streams v:0 \
  -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 \
  input.mkv

输出示例

  2600
  • 在此示例中, 2600 的输出是指读取帧数.
  • 由于整个文件必须解码,所以命令可能需要一段时间才能完成,具体取决于您的输入.

这个选项是什么意思

  • -v error 这将隐藏”info”输出(版本信息等),使解析更容易.
  • -count_frames 计算每个流的帧数,并在相应的流片段中进行报告.
  • -select_streams v:0 只选择视频流.
  • -show_entries stream = nb_read_frames 只显示读取帧数.
  • -of default = nokey = 1:noprint_wrappers = 1 将输出格式(也称为”writer”)设置为 default ,请勿打印每个字段( nokey = 1 ),并且不打印部分页眉和页脚( noprint_wrappers = 1 ).

 

 

 

主机间数据拷贝:scp/rsync/aria2c/wget/curl

ref: https://www.ibm.com/developerworks/cn/linux/l-cn-filetransfer/

scp SRC DST:

scp -r SRC_DIR DST_DIR:

 

支持断点续传

rsync -P –rsh=ssh home.tar 192.168.205.34:/home/home.tar  (password is required)

rsync -P –rsh=”ssh -i key”  username@ip:/data/bw_mon/bw_mysqlbk/local_data/20140414_0415.tar.gz ./

eg:  rsync -avzP file root@172.20.7.219:/root/tmp

 

断点续传,多线程分块下载(大文件)

aria2c -c –max-concurrent-downloads=25 –check-integrity=true https://lmb.informatik.uni-freiburg.de/data/SceneFlowDatasets_CVPR16/Release_april16/data/Monkaa/raw_data/monkaa__frames_finalpass_webp.tar

wget -c URL:支持断点续传

 

 

ftp

ftp 命令使用文件传输协议(File Transfer Protocol, FTP)在本地主机和远程主机之间或者在两个远程主机之间进行文件传输。

FTP 协议允许数据在不同文件系统的主机之间传输。尽管这个协议在传输数据上提供了高适应性,但是它并没有尝试去保留一个特定文件系统上的文件属性(例如一个文件的保护模式或者修改次数)。而且 FTP 协议很少对一个文件系统的整体结构作假定,也不提供这样的功能,比如递归的拷贝子目录。在使用 ftp 命令时,需要注意 FTP 协议的这些特性。当需要保留文件属性或者需要递归的拷贝子目录时,可以使用 rcp/scp 等命令。

基本语法

ftp 命令的一般格式如下:

$ ftp 主机名 /IP

其中“主机名 /IP ”是所要连接的远程机的主机名或 IP 地址。在命令行中,主机名属于可选项,如果指定主机名,ftp 将试图与远程机的 ftp 服务程序进行连接;如果没有指定主机名,ftp 将给出提示符,等待用户输入命令:

1
2
$ ftp
 ftp >

此时在 ftp> 提示符后面输入 open 子命令加主机名或 IP 地址,将试图连接指定的主机。不管使用哪一种方法,如果连接成功,需要在远程机上登录。用户如果在远程机上有帐号,就可以通过 ftp 使用这一帐号并需要提供口令。在远程机上的用户帐号的读写权限决定该用户在远程机上能下载什么文件和能将上载文件放到哪个目录中。在远程站点上登录成功后,在“ ftp> ”提示符下可以自由使用 ftp 提供的各种子命令,最常用的子命令如下表所示。

表 1. ftp 子命令

使用实例:

利用编写 ftp 脚本可以自动完成文件传输任务。具体方法是使用 ftp 命令的 -in 选项,并重定向 ftp 命令的输入。现在我们来编写一个利用 ftp 登录到远程服务器,并以 bin 的文件格式,在 /home 目录下,下载 file1.log 以及 file2.sh 至本机 /opt/ibm/,并从本地 /opt 目录上传文件 file3.jave 至远程服务器 /home 的自动化脚本。

1
2
3
4
5
6
7
8
9
10
11
ftp -ni <<+
     open $IP
     user $USERNAME $PASSWD
     bin
     cd /home
     lcd /opt/ibm
     mget file1.log file2.sh
     lcd /opt
     mput file3.jave
     ls
     bye

rcp

rcp 意为“ remote file copy ”(远程文件拷贝)。该命令用于计算机之间进行文件拷贝。其有两种格式。第一种格式用于文件到文件的拷贝;第二种格式用于把文件或目录拷贝到另一个目录中。

基本语法

1
2
rcp [-px] [-k realm] file1 file2
 rcp [-px] [-r] [-k realm] file directory

每个文件或目录参数既可以是远程文件名也可以是本地文件名。远程文件名具有如下形式:rname@rhost:path,其中 rname 为远程用户名,rhost 为远程计算机名,path 为该文件的路径。下表说明了 rcp 命令各个参数的含义。

表 2. rcp 命令的命令行参数

如果在文件名中指定的路径不是完整的路径名,则该路径将被解释为相对远程机上同名用户的主目录。若没有给出远程用户名,则使用当前用户名。如果远程机上的路径包含特殊 shell 字符,需要使用反斜线(\)、双引号(”)或单引号(’)将其括起来,使所有的 shell 元字符都能被远程地解释。需要说明的是,rcp 不提示输入口令,它通过 rsh(remote shell)命令来执行拷贝。

使用实例:

  • 将本地文件复制到远程登录目录中rcp <source> <remoteDir>
  • 将多个本地文件复制到远程登录目录的子目录中rcp <source1> <source2> <source3> <subdirectory in remote system>
  • 将多个文件从多个远程源复制到使用不同用户名的远程目标中rcp <host1.user1:source1> <host2.user2:source2> <dest.destuser:directory>

scp

scp 命令在网络上的主机之间拷贝文件,它是安全拷贝(secure copy)的缩写。 scp 命令使用 ssh 来传输数据,并使用与 ssh 相同的认证模式,提供同样的安全保障。 scp 命令的用法和 rcp 命令非常类似,这里就不做过多介绍了。一般推荐使用 scp 命令,因为它比 rcp 更安全。

我们可以通过配置 ssh,使得在两台机器间拷贝文件时不需要每次都输入用户名和密码。

基本语法

1
2
3
scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
         [-l limit] [-o ssh_option] [-P port] [-S program]
         [[user@]host1:]file1 [...] [[user@]host2:]file2

使用 scp 命令,需要输入密码,如果不想每次都输入,可参考下面的方法。

首先生成密钥对

1
2
3
4
5
6
7
8
9
10
$ ssh-keygen -t rsa
 Generating public/private rsa key pair.
 Enter file in which to save the key (/home/user/.ssh/id_rsa):
 Created directory '/home/user/.ssh'.
 Enter passphrase (empty for no passphrase):
 Enter same passphrase again:
 Your identification has been saved in /home/user/.ssh/id_rsa.
 Your public key has been saved in /home/user/.ssh/id_rsa.pub.
 The key fingerprint is:
 10:66:da:38:85:8a:8c:bd:db:9c:6e:eb:ee:bd:7d:15 user@somehost

在这里,我们指定了生成 rsa 类型的密钥。在提示密钥的保存路径和密码时,可以直接回车使用默认路径和空密码。这样,生成的公共密钥保存在 $HOME/.ssh/id_rsa.pub,私有密钥保存在 $HOME/.ssh/id_rsa 。然后把这个密钥对中的公共密钥的内容复制到要访问的机器上的 $HOME/.ssh/authorized_keys 文件中。这样,下次再访问那台机器时,就不用输入密码了。

使用实例:

  • Copy 本地文件 /etc/eva.log, 到远程机器 sysB, 用户 user 的家目录下scp /etc/eva.log user@sysB:/home/user
  • copy 远程机器 sysB 上的文件 /home/uesr/eva.log, 到本地的 /etc 目录下 , 并保持文件属性不变scp -p user@sysB:/home/uesr/eva.log /etc
  • copy sysB 上的目录 /home/user, 到本地 /home/user/tmp, <new dir,/home/user/tmp/user>scp -r user@sysB:/home/user /home/user/tmp

wget

wget 是一个经由 GPL 许可的可从网络上自动获取文件的自由软件包。它是一个非交互式的命令行工具。支持 HTTP,HTTPS 和 FTP 协议,支持代理服务器以及断点续传功能。 wget 可实现递归下载,即可跟踪 HTML 页面上的链接依次下载来创建远程服务器的本地版本,完全重建原始站点的目录结构,实现远程网站的镜像。在递归下载时,wget 将页面中的超级链接转换成指向本地文件,方便离线浏览。由于非交互特性,wget 支持后台运行,用户在退出系统后,仍可继续运行。功能强大,设置方便简单。

基本语法

1
wget [options] [URL-list]

wget 有很多不同的参数以用于远程站点信息的获取,常用参数如下,更多参数请参照 wget 帮助手册 http://www.gnu.org/software/wget/manual/wget.html

表 3. wget 工具常用参数

使用实例:

  • 递归下载 http://www.ibm.com.cn 站点的信息。下载所有显示完整网页所以需要的文件,如图片等。在下载不进行上层目录搜索并将绝对链接转换为相对链接。
    wget -r -p -np -k http://www.ibm.com.cn
  • 将在本地硬盘建立 http://www.ibm.com.cn 的镜像,镜像文件存入当前目录下一个名为 www.ibm.com.cn 的子目录中(也可以使用 -nH 参数指定不建立该子目录,而直接在当前目录下建立镜像的目录结构),递归深度为 4,重试次数为无穷(若连接出现问题,wget 将永远重试下去,直至任务完成)
    wget -m -l4 -t0 http://www.ibm.com.c
  • 使用代理进行下载,并实现断点续传。代理可以在环境变量 PROXY 或 wgetrc 文件中设定。 -c 选项要求服务支持断点续传。
    wget -Y on -c http://www.ibm.com.cn

curl

另一个可以用来进行文件传输的工具是 curl,它是对 libcurl 库的一个命令行工具包装。 libcurl 库中提供了相应功能的 API,可以在程序中调用。对于 libcurl 库的使用方法介绍超出了本文的讨论范围。 curl 使用 URL 的语法来传输文件,它支持 FTP, FTPS, HTTP, HTTPS, TFTP, SFTP, TELNET 等多种协议。 curl 功能强大,它提供了包括代理支持,用户认证,FTP 上载,HTTP post,SSL 连接,文件续传等许多特性。

基本语法

1
curl [options … ] <url>

其中下载参数大约有 80 多个,curl 的各个功能完全依靠这些参数来完成。下面举例说明 curl 的一些基本用法。

使用实例:

  • 获取 GNU 的主页curl http://www.gnu.org
  • 获取 GNU 的 FTP 服务器上根目录下的 README 文件curl ftp://ftp.gnu.org/README
  • 从一个字典中获取 curl 的定义curl dict://dict.org/m:curl
  • 如果需要指定用户名和密码的话,可以在 url 中指定,或者使用 -u 参数curl ftp://name:passwd@machine.domain:port/full/path/to/filecurl -u name:passwd ftp://machine.domain:port/full/path/to/file
  • curl 会将从指定 url 处获取的内容打印到标准输出上。如果需要保存在本地文件中,可以使用 -o,或使用 -O 参数指定使用远程主机上的文件名(如果 url 中没有给出文件名的部分,则此操作将会失败)curl – o gnu.html http://www.gnu.orgcurl – O http://www.gnu.org/index.html
  • 使用 -x 选项来使用代理进行连接curl -x my-proxy:port ftp://ftp.somesite.com/README
  • 通过使用 curl 的 -T 选项来进行上载curl -T – ftp://ftp.upload.com/upfile
  • 此命令从标准输入读取数据,并上载至远程 FTP 服务器上的 upfile 文件中。也可以指定上载一个本地文件curl -T localfile -a ftp://ftp.upload.com/upfile其中 -a 参数表示以添加方式将 localfile 中的内容附加到 upfile 的末尾。

总的来说,curl 适合用来进行自动的文件传输或操作序列,它是一个很好的模拟用户在网页浏览器上的行为的工具。尤其当需要在程序中调用时,libcurl 是个很好的选择。

rsync

rsync 是一款高效的远程数据备份和镜象工具,可快速地同步多台主机间的文件,其具有如下特性:

  • 支持链接、所有者、组信息以及权限信息的拷贝;
  • 通过远程 shell(ssh, rsh)进行传输;
  • 无须特殊权限即可安装使用;
  • 流水线式文件传输模式,文件传输效率高;
  • 支持匿名操作;

需要提及的是 rsync 以其优越的性能优势区别于其它几种 Linux 文件传输方法,其同步文件的速度相当快,这主要归功于 rsync 所使用的传输算法。简而言之 rsync 算法能在相当短的时间内计算出需要备份的数据,只对源文件与目标文件的不同之处进行传输,从而降低网络中传输的数据量,以此达到快速备份镜像的目的。下面通过一典型应用场景来描述 rsync 算法的基本原理:主机 A 与主机 B 均有对同一文件的拷贝,用户对主机 A 上的拷贝进行更新,主机 B 通过 rsync 算法对更新后的文件进行同步。以下是该算法的实现步骤:

  1. 主机 B 将原始拷贝划分成大小为 N 的不重合的若干块(文件末尾部分分块大小可能不足 N),并对这些数据块进行两种不同方式的校验:32 位的滚动弱校验、128 位的 MD4 强校验。弱校验较之强校验计算速度快。
  2. 主机 B 将每个数据块的弱校验、强校验结果发送给主机 A 。
  3. 主机 A 对更新后的文件拷贝中的每个长度为 N 的数据块进行弱校验并与从 B 接收到的弱校验值进行匹配,若相同再进行强校验匹配。由于弱校验的滚动特性可以快速地筛选出需要进行同步的数据块。该算法的运算量主要集中在主机 A 上。
  4. 通过上述计算,主机 A 将文件的不同部分发送给 B,B 接收到两个拷贝之间的不同之处,从而同步得到更新后的文件。

通过如上方式,rsync 避免了对相同数据的传输,减少了网络带宽的浪费。在时间上整个过程中需一个往返,从某种程度上也保证了 rsync 的优越性能。

用户可从官方网站 http://rsync.samba.org/ 上下载安装 rsync 的最新版本。使用时需将 rsync 分别安装于服务端和客户端,服务端和客户端使用同一个 rsync 软件包来实现远程镜像和定期同步更新。需要说明的是一个 rsync 服务端可同时备份多个客户端的数据;多个服务端备份一个客户端的数据。 rsync 默认端口为 873,服务器在该端口接收客户的匿名或者认证方式的备份请求。

rsync 服务端在使用之前需要进行必要的配置,其配置文件为 /etc/rsyncd.conf,进行认证、访问、日志记录等控制。配置文件包括全局参数、模块参数的设置。 rsyncd.conf 文件中 [module] 之前的所有参数为全局参数,也可以在全局参数部分定义模块参数,在这种情况下该参数的值就是所有模块的默认值。全局参数设置程序使用的端口号,指定消息文件、日志文件 pid 文件以及发送日志消息的级别。模块参数主要定义服务端哪个目录需要被同步。用户可根据不同的需要指定多个模块,每个模块对应需要备份的一个目录树,即若有 N 个需要备份的目录树,则需要 N 个模块与之对应。模块中可以定义许多参数,常见参数如下。

表 4. rsyncd.conf 配置文件常见模块参数列表

基本语法

  • 通过远程 shell 方式:
  • rsync [OPTION] [USER@]HOST:SRC DEST
  • 使用远程 shell(如 ssh, rsh)实现将远程机器的内容拷贝到本地机器。 SRC 地址路径中以单个冒号 “:” 进行分隔。
  • rsync [OPTION] SRC [USER@]HOST:DEST
  • 使用远程 shell(如 rsh、ssh)实现本地机器的内容拷贝到远程机器。 DEST 地址路径中以单个冒号 “:” 进行分隔。
  • 通过 rsync daemon 方式:
  • rsync [OPTION] [USER@]HOST::SRC DEST 或
  • rsync [OPTION] rsync://[USER@]HOST[:PORT]/SRC [DEST]
  • 从远程 rsync 服务器中拷贝文件到本地机。 SRC 地址路径中以双冒号 “::” 进行分隔。
  • rsync [OPTION] SRC [USER@]HOST::DEST 或
  • rsync [OPTION] SRC rsync://[USER@]HOST[:PORT]/DEST
  • 从本地机器拷贝文件到远程 rsync 服务器中。 DEST 地址路径中以双冒号 “::” 进行分隔。

如果 rsync 命令中只指定 SRC 参数而不指定 DEST 参数,则意为显示源文件列表而非进行同步拷贝。 rsync 有许多功能选项,常用的选项如下:

表 5. rsync 常用参数

使用实例:

  • 查看服务端文件及列表
    • # rsync 9.186.110.53::查看服务端可用的模块列表以及注释信息
    • # rsync ibmuser@9.186.110.53::www/查看服务端 www 模块中的目录及文件列表(使用 rsyncd 用户认证方式)
    • # rsync ibmuser@9.186.110.53:/www/wwwroot/shockjiang.vip/查看服务端 /www/wwwroot/shockjiang.vip 目录中的内容(使用服务端的系统用户进行验证,如 ibmuser)
  • 保持客户端与服务端的数据同步
    • # rsync -avz ibmuser@9.186.110.53::www/ /backup1/使用后台服务方式将服务端 www 模块下的内容备份到本地 /backup1 目录中,备份时保留原有权限、属性、属主及符号连接等,并使用压缩方式加快数据传输。
    • # rsync – avz ibmuser@9.186.110.53:/www/wwwroot/shockjiang.vip /backup2/使用 ssh 方式将远程的 /www/wwwroot/shockjiang.vip 目录备份到本地 /backup2/ 目录下
    • # rsync -avz –delete ibmuser@9.186.110.53::www/ /backup3/将远程 www 模块备份到本地 /backup3/ 目录中,同时进行同步目录,删除本地目录中多余的文件。

当服务端的数据出现问题时,需要通过客户端的数据对服务端进行恢复,只要客户端有服务端的写入权限,即可通过调换 rsync 命令的 SRC、DEST 参数进行恢复。

结尾与总结

综上所述,各种文件传输方式的特征表现各有千秋,我们从以下几个方面综合对比,更深入地了解它们各自的特性。

  • 传输性能

wget 通过支持后台执行及断点续传提高文件传输效率 ; rsync 则以其高效的传输及压缩算法达到快传输的目的。

  • 配置难度

rcp 只需进行简单的配置,创建 .rhost 文件以及设置 /etc/hosts 文件中主机名与 IP 地址列表; wget 设置设置方便简单,只需在客户端指定参数执行命令即可; rsync 在使用前需要对服务端 /etc/rsyncd.conf 进行参数设定,配置内容相对复杂。

  • 安全性能

ftp、rcp 不保证传输的安全性,scp、rsync 则均可基于 ssh 认证进行传输,提供了较强的安全保障。 wget 也可通过指定安全协议做到安全传输。

通过上述的对比不难发现,每种文件传输方法基于其自身的特点与优势均有其典型的适用场景:

  • ftp 作为最常用的入门式的文件传输方法,使用简单,易于理解,并且可以实现脚本自动化;
  • rcp 相对于 ftp 可以保留文件属性并可递归的拷贝子目录;
  • scp 利用 ssh 传输数据,并使用与 ssh 相同的认证模式,相对于 rcp 提供更强的安全保障;
  • wget,实现递归下载,可跟踪 HTML 页面上的链接依次下载来创建远程服务器的本地版本,完全重建原始站点的目录结构,适合实现远程网站的镜像;
  • curl 则适合用来进行自动的文件传输或操作序列,是一个很好的模拟用户在网页浏览器上的行为的工具;
  • rsync 更适用于大数据量的每日同步,拷贝的速度很快,相对 wget 来说速度快且安全高效。

 

 

supervisor conf: 程序管理与自动运行

ref:http://liyangliang.me/posts/2015/06/using-supervisor/

使用 supervisor 管理进程

Supervisor (http://supervisord.org) 是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程,比如很不幸的服务器出问题导致所有应用程序都被杀死,此时可以用 supervisor 同时启动所有应用程序而不是一个一个地敲命令启动。

安装

Supervisor 可以运行在 Linux、Mac OS X 上。如前所述,supervisor 是 Python 编写的,所以安装起来也很方便,可以直接用 pip :

sudo pip install supervisor

如果是 Ubuntu 系统,还可以使用 apt-get 安装。

supervisord 配置

Supervisor 相当强大,提供了很丰富的功能,不过我们可能只需要用到其中一小部分。安装完成之后,可以编写配置文件,来满足自己的需求。为了方便,我们把配置分成两部分:supervisord(supervisor 是一个 C/S 模型的程序,这是 server 端,对应的有 client 端:supervisorctl)和应用程序(即我们要管理的程序)。

首先来看 supervisord 的配置文件。安装完 supervisor 之后,可以运行echo_supervisord_conf 命令输出默认的配置项,也可以重定向到一个配置文件里:

echo_supervisord_conf > /etc/supervisord.conf

去除里面大部分注释和“不相关”的部分,我们可以先看这些配置:

[unix_http_server]
file=/tmp/supervisor.sock   ; UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ; socket 文件的 mode,默认是 0700
;chown=nobody:nogroup       ; socket 文件的 owner,格式: uid:gid

;[inet_http_server]         ; HTTP 服务器,提供 web 管理界面
;port=127.0.0.1:9001        ; Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性
;username=user              ; 登录管理后台的用户名
;password=123               ; 登录管理后台的密码

[supervisord]
logfile=/tmp/supervisord.log ; 日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB        ; 日志文件大小,超出会 rotate,默认 50MB
logfile_backups=10           ; 日志文件保留备份数量默认 10
loglevel=info                ; 日志级别,默认 info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ; pid 文件
nodaemon=false               ; 是否在前台启动,默认是 false,即以 daemon 的方式启动
minfds=1024                  ; 可以打开的文件描述符的最小值,默认 1024
minprocs=200                 ; 可以打开的进程数的最小值,默认 200

; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; 通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致
;serverurl=http://127.0.0.1:9001 ; 通过 HTTP 的方式连接 supervisord

; 包含其他的配置文件
[include]
files = relative/directory/*.ini    ; 可以是 *.conf 或 *.ini

我们把上面这部分配置保存到 /etc/supervisord.conf(或其他任意有权限访问的文件),然后启动 supervisord(通过 -c 选项指定配置文件路径,如果不指定会按照这个顺序查找配置文件:$CWD/supervisord.conf, $CWD/etc/supervisord.conf, /etc/supervisord.conf):

supervisord -c /etc/supervisord.conf

查看 supervisord 是否在运行:

ps aux | grep supervisord

program 配置

上面我们已经把 supervisrod 运行起来了,现在可以添加我们要管理的进程的配置文件。可以把所有配置项都写到 supervisord.conf 文件里,但并不推荐这样做,而是通过 include 的方式把不同的程序(组)写到不同的配置文件里。

为了举例,我们新建一个目录 /etc/supervisor/ 用于存放这些配置文件,相应的,把 /etc/supervisord.conf 里 include 部分的的配置修改一下:

[include]
files = /etc/supervisor/*.conf

假设有个用 Python 和 Flask 框架编写的用户中心系统,取名 usercenter,用 gunicorn (http://gunicorn.org/) 做 web 服务器。项目代码位于 /home/leon/projects/usercenter,gunicorn 配置文件为 gunicorn.py,WSGI callable 是 wsgi.py 里的 app 属性。所以直接在命令行启动的方式可能是这样的:

cd /home/leon/projects/usercenter
gunicorn -c gunicorn.py wsgi:app

现在编写一份配置文件来管理这个进程(需要注意:用 supervisord 管理时,gunicorn 的 daemon 选项需要设置为 False):

[program:usercenter]
directory = /home/leon/projects/usercenter ; 程序的启动目录
command = gunicorn -c gunicorn.py wsgi:app  ; 启动命令,可以看出与手动在命令行启动的命令是一样的
autostart = true     ; 在 supervisord 启动的时候也自动启动
startsecs = 5        ; 启动 5 秒后没有异常退出,就当作已经正常启动了
autorestart = true   ; 程序异常退出后自动重启
startretries = 3     ; 启动失败自动重试次数,默认是 3
user = leon          ; 用哪个用户启动
redirect_stderr = true  ; 把 stderr 重定向到 stdout,默认 false
stdout_logfile_maxbytes = 20MB  ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups = 20     ; stdout 日志文件备份数
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile = /data/logs/usercenter_stdout.log

; 可以通过 environment 来添加需要的环境变量,一种常见的用法是修改 PYTHONPATH
; environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere

一份配置文件至少需要一个 [program:x] 部分的配置,来告诉 supervisord 需要管理那个进程。[program:x] 语法中的 x 表示 program name,会在客户端(supervisorctl 或 web 界面)显示,在 supervisorctl 中通过这个值来对程序进行 start、restart、stop 等操作。

使用 supervisorctl

Supervisorctl 是 supervisord 的一个命令行客户端工具,启动时需要指定与 supervisord 使用同一份配置文件,否则与 supervisord 一样按照顺序查找配置文件。

supervisorctl -c /etc/supervisord.conf

上面这个命令会进入 supervisorctl 的 shell 界面,然后可以执行不同的命令了:

> status    # 查看程序状态
> stop usercenter   # 关闭 usercenter 程序
> start usercenter  # 启动 usercenter 程序
> restart usercenter    # 重启 usercenter 程序
> reread    # 读取有更新(增加)的配置文件,不会启动新添加的程序
> update    # 重启配置文件修改过的程序

上面这些命令都有相应的输出,除了进入 supervisorctl 的 shell 界面,也可以直接在 bash 终端运行:

$ supervisorctl status
$ supervisorctl stop usercenter
$ supervisorctl start usercenter
$ supervisorctl restart usercenter
$ supervisorctl reread
$ supervisorctl update 

其它

除了 supervisorctl 之外,还可以配置 supervisrod 启动 web 管理界面,这个 web 后台使用 Basic Auth 的方式进行身份认证。

除了单个进程的控制,还可以配置 group,进行分组管理。

经常查看日志文件,包括 supervisord 的日志和各个 pragram 的日志文件,程序 crash 或抛出异常的信息一半会输出到 stderr,可以查看相应的日志文件来查找问题。

Supervisor 有很丰富的功能,还有其他很多项配置,可以在官方文档获取更多信息:http://supervisord.org/index.html

 

使用aria2c下载进程的conf范例:

[program:download]
directory = /home/shock/cvdownload ; 程序的启动目录
command = aria2c -c –max-concurrent-downloads=25 –check-integrity=true –split=25 http://lmb.informatik.uni-freiburg.de/data/SceneFlowDatasets_CVPR16/Release_april16/data/FlyingThings3D/derived_data/flyingthings3d__optical_flow.tar.bz2
autostart = true ; 在 supervisord 启动的时候也自动启动
startsecs = 5 ; 启动 5 秒后没有异常退出,就当作已经正常启动了
autorestart = true ; 程序异常退出后自动重启
startretries = 3 ; 启动失败自动重试次数,默认是 3
user = shock ; 用哪个用户启动
redirect_stderr = true ; 把 stderr 重定向到 stdout,默认 false
stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups = 20 ; stdout 日志文件备份数
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile = /home/shock/cvdownload/supervisor_download.log

rsync config

rsyncd_server.conf:
uid = root
gid = root
use chroot = no
max connections = 100
strict modes = yes
pid file = /webserver/logs/rsync.pid
log file = /webserver/logs/rsyncd.log
ignore error = yes
timeout = 300

[data]
path = /data
read only = no
write only = no
hosts allow = *
list = false
uid = root
gid = root
auth users = root
secrets file = /webserver/rsync/rsyncd_server.passwd

[image]
path = /data/res/static/photos
read only = no
write only = no
hosts allow = *
list = false
uid = root
gid = root
auth users = root
secrets file = /webserver/rsync/rsyncd_server.passwd

rsync.sh:
#!/bin/bash
src1=/media
src2=/webserver
rsync_passwd_file=/webserver/rsync/rsyncd_server.passwd

if [ ! -e “$src1” ] || [ ! -e “$src2” ] || [ ! -e “/usr/bin/rsync” ] || [ ! -e “$rsync_passwd_file” ]; then
echo “Check File and Folder”
exit 1
fi
rsync –daemon –config=/webserver/rsync/rsyncd.conf

inotify.sh:
/usr/bin/killall -9 inotifywait
/bin/sleep 2
/usr/bin/killall -9 rsync
/bin/sleep 2
src=/data
des=data
rsync_passwd_file=/home/kandao/workspace/rms/scripts/rsync_copy/rsyncd_client.passwd
ip=portalxxx.kandaoxx.tech
# server auth name
user=root

# check
if [ ! -e “${src}” ] || [ ! -e “/usr/bin/inotifywait” ] || [ ! -e “/usr/bin/rsync” ] || [ ! -e “${rsync_passwd_file}” ]; then
echo “Check File and Folder”
exit 1
fi
# need cd into local path
cd ${src}
/usr/bin/inotifywait -mrq –format ‘%Xe %w%f’ -e modify,create,delete,attrib,close_write,move ./ | while read file
do
INO_EVENT=$(echo $file | awk ‘{print $1}’)
INO_FILE=$(echo $file | awk ‘{print $2}’)
echo “——————————-$(date)————————————”
echo $file
# create,modify,close_write,move to
if [[ $INO_EVENT =~ ‘CREATE’ ]] || [[ $INO_EVENT =~ ‘MODIFY’ ]] || [[ $INO_EVENT =~ ‘CLOSE_WRITE’ ]] || [[ $INO_EVENT =~ ‘MOVED_TO’ ]]
then
echo ‘CREATE or MODIFY or CLOSE_WRITE or MOVED_TO’
rsync -avzctRP –password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) –exclude-from=/data/rsyncexclude.txt ${user}@${ip}::${des}
fi
# delete move from
if [[ $INO_EVENT =~ ‘DELETE’ ]] || [[ $INO_EVENT =~ ‘MOVED_FROM’ ]]
then
echo ‘DELETE or MOVED_FROM’
rsync -avztRP –password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) –exclude-from=/data/rsyncexclude.txt ${user}@${ip}::${des}
fi
# touch chgrp chmod chown
if [[ $INO_EVENT =~ ‘ATTRIB’ ]]
then
echo ‘ATTRIB’
if [ ! -d “$INO_FILE” ]
then
rsync -avzctRP –password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) –exclude-from=/data/rsyncexclude.txt ${user}@${ip}::${des}
fi
fi
done

rsyncd_server.passwd
root:xxxxpassword

rsyncd_client.passwd
xxxxpassword

rsyncexclude.txt
origin
origin/*
_thumbnails
_thumbnails/*
WEBM
WEBM/*
rsyncexclude.txt

dante+socks5+switchyomega

1.安装dante-server: sudo apt-get install dante-server

2. 修改配置文件:
mv /etc/danted.conf /etc/danted.conf.bak
新建配置文件
touch /etc/danted.conf
nano /etc/danted.conf

logoutput: /var/log/danted.log
internal: eth0 port = 1080
external: eth0
method: username none
user.privileged: proxy
user.notprivileged: nobody
user.libwrap: nobody
client pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
log: connect disconnect
}
pass {
from: 0.0.0.0/0 to: 0.0.0.0/0 port gt 1023
command: bind
log: connect disconnect
}
pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
command: connect udpassociate
log: connect disconnect
}
block {
from: 0.0.0.0/0 to: 0.0.0.0/0
log: connect error
}

3.创建log文件夹
mkdir /var/log/sockd

4.启动Dante
/etc/init.d/danted start
02.png

5.检测是否启动成功
netstat -anp | grep 1080

6. 设置chrome
设置switchyomega: 并配置
or proxyhelper

ps: switchyomega的配置文件:https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt

or

pip install shadowsocks

socks5.json
{
“server”:”ip_of_server”,
“server_port”:6443,
“local_port”:1080,
“password”:”password”,
“timeout”:600,
“method”:”aes-256-cfb”
}

sslocal -c socks5.json

 

ftp config

0. install
sudo apt-get install libpam-pwdfile vsftpd apache2-utils
/usr/sbin/vsftpd

1. Edit /etc/vsftpd.conf
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
local_root=/ftp/data
chroot_local_user=YES
allow_writeable_chroot=YES
hide_ids=YES
ftpd_banner=Welcome to Kandao Tech Ltd.

xferlog_enable=YES
xferlog_std_format=YES
xferlog_file=/var/log/xferlog
dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd.log

#virutal user settings
user_config_dir=/etc/vsftpd_user_conf
guest_enable=YES
virtual_use_local_privs=YES
pam_service_name=vsftpd
nopriv_user=vsftpd
guest_username=vsftpd

2. Edit /etc/pam.d/vsftpd
auth required pam_pwdfile.so pwdfile /etc/vsftpd/ftpd.passwd
account required pam_permit.so

3. Add a system user for virtual users
useradd –home /home/vsftd –gid nogroup -m –shell /bin/false vsftpd

4. Create virtual users
mkdir /etc/vsftpd
htpasswd -d /etc/vsftpd/ftpd.passwd pub (passpub)
5. Create user conf file
mkdir /etc/vsftpd_user_conf

echo “local_root=/ftp/data/pub”>/etc/vsftpd_user_conf/pub
6. Make user directory
mkdir /ftp/data/pub; chown vsftpd:nogroup /ftp/data/pub

7. retart vsftpd
service vsftpd restart
or /usr/sbin/vsftpd

8. ssl support
1) check whether vsftpd support ssl:
ldd /usr/sbin/vsftpd |grep libssl
2) generate cert
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /etc/vsftpd/vsftpd.pem -out /etc/vsftpd/vsftpd.pem
3) edit conf:
vi /etc/vsftpd/vsftpd.conf
add following lines:

ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
rsa_cert_file=/etc/vsftpd/vsftpd.pem

3) restart: service vsftpd restart

FIFO 读写

ref: http://blog.csdn.net/erlian_beijing/article/details/46698401

FIFO文

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo( const char*pathname, mode_t mode);

参数:

pathname:FIFO的路径名+文件名。

mode:mode_t类型的权限描述符,同open的参数。

返回值:

成功:返回0

失败:如果文件已经存在,则会出错且返回-1。

 

操作FIFO文件时的特点:

系统调用的I/O函数都可以作用于FIFO,如open、close、read、write等。

 

打开FIFO时,非阻塞标志(O_NONBLOCK)产生下列影响:

特点一:不指定O_NONBLOCK(即open没有位或O_NONBLOCK)

1、open以只读方式打开FIFO时,要阻塞到某个进程为写而打开此FIFO

2、open以只写方式打开FIFO时,要阻塞到某个进程为读而打开此FIFO。

3、open以只读、只写方式打开FIFO时会阻塞,调用read函数从FIFO里读数据时read也会阻塞。

4、调用write函数向FIFO里写数据,当缓冲区已满时write也会阻塞。

5、通信过程中若写进程先退出了,则调用read函数从FIFO里读数据时不阻塞;若写进程又重新运行,则调用read函数从FIFO里读数据时又恢复阻塞。

6、通信过程中,读进程退出后,写进程向命名管道内写数据时,写进程也会(收到SIGPIPE信号)退出。

特点二:指定O_NONBLOCK(即open位或O_NONBLOCK)

1、先以只读方式打开:如果没有进程已经为写而打开一个FIFO, 只读open成功,并且open不阻塞。

2、先以只写方式打开:如果没有进程已经为读而打开一个FIFO,只写open将出错返回-1。

3、read、write读写命名管道中读数据时不阻塞。

4、通信过程中,读进程退出后,写进程向命名管道内写数据时,写进程也会(收到SIGPIPE信号)退出。

 

注意:

open函数以可读可写方式打开FIFO文件时的特点:open不阻塞,可以这样理解:因为其本身以可读可写的方式打开,所以不需要别的进程帮其打开。

 

注:关于非阻塞方式或非阻塞打开FIFO,read时返回值的问题:

 

若某个FIFO的最后一个写进程终止了或关闭了该FIFO,那么将为FIFO的读进程产生一个文件结束标志。如果 read()读数据时第一个读到的是文件结束标志,那么就返回0。

 

1、阻塞方式:

1) 写进程未退出,read阻塞,等待写端的输入

2) 写进程终止了或关闭了该FIFO,read非阻塞,为FIFO的读进程产生一个文件结束标志,read的返回值为0。

 

2、非阻塞方式:

假设一个进程以非阻塞读方式打开一个FIFO.该FIFO之前已经被以写方式被其他进程打开,但无数据被写入,那么此时读进程需要立刻返回,那么应该返回什么呢?
我们知道 如果 read()读数据时第一个读到的是文件结束标志,那么就返回0。如果像 我们想的那样 没有数据读应该返回0 ,那么这个0就具有二义性。因为我们不知道是没有数据造成的返回0还是写端关闭造成的返回0.

所以POSIX.1要求,对一个非阻塞的描述符如果无数据可读,则read返回-1,而且 errno被设置为 EAGAIN。

1) 如果在随后调用read函数之前,如果另一个进程已经以写方式打开了该FIFO,并写入了数据,那么正常读取数据。

2) 如果在随后调用read函数之前,如果另一个进程已经以写方式打开了该FIFO,但是并未写入数据,read调用会立刻出错返回-1, 并设置 errnno为EAGAIN。

3)如果在随后调用read函数之前,没有其他进程以写方式打开该FIFO,或是曾经有但是在read读时已经关闭了,那么read返回0,表示读到文件结束标志。