要想通过newlisp远程执行命令,首先要熟悉ssh远程执行命令
这里有一个例子,想要在远程服务器上安装emacs,可以这么做
# ssh -t 10.149.11.157 'export http_proxy="http://10.180.86.30:3128" && yum install emacs'
说明:
1. 由于远程服务器无法访问外网,先设置proxy, 之后再运行yum install emacs
2. 由于当前服务器已经和远程服务器建立了ssh认证,无需输入用户名和密码
3. -t 参数可以在本机获得远程服务器的虚拟tty终端,如果有什么需要交互的,在本机即可完成操作,比如下面问y/N
Total download size: 22 M
Installed size: 73 M
Is this ok [y/N]: y
y
现在用newlisp对其包装,主要是需要一个文件提供所有需要操作的的IP地址, 然后利用newlisp生成一个.sh文件,里面包含各种ssh命令。
hosts.lsp里面包含了各个远程服务器的IP地址:
(set 'remotes '("10.149.11.156" "10.149.11.157" "10.149.11.158" "10.149.11.159" "10.149.11.160" "10.149.11.161"))
gen_remote_cmds.lsp文件代码如下:
#!/usr/bin/newlisp
(println "this util will help to generate commands on remote server using newlisp and ssh")
(println "example: " "./gen_remote_cmds.lsp your-cmd your-hosts.lsp")
(set 'cmd (main-args 2))
(set 'hosts (main-args 3))
(load hosts)
(if (file? "output.sh")
(delete-file "output.sh"))
(append-file "output.sh" "#!/bin/bash")
(append-file "output.sh" "\n")
(dolist (host remotes)
(set 'cmd2 (string "ssh -t " host " '" cmd "'"))
(append-file "output.sh" cmd2)
(append-file "output.sh" "\n")
)
(exit)
# ./gen_remote_cmds.lsp 'export http_proxy="http://10.180.86.30:3128" && yum install emacs' ./hosts.lsp
this util will help to generate commands on remote server using newlisp and ssh
example: ./gen_remote_cmds.lsp your-cmd your-hosts.lsp
然后运行,期间会提示输入一些y, 很快乐的远程安装了一批emacs.
由于经常要在各个服务器上执行一批命令,所以希望将这些命令放在一个文件中,newlisp解析并生成文件,文件中包含所有服务器上需要运行的命令。
./gen_remote_cmds.lsp hosts.lsp dir_cmd.txt m.sh
mkdir -p /data/slot0/lisa/hdfs/namenode
mkdir -p /data/slot0/lisa/hdfs/journalnode
mkdir -p /data/slot0/lisa/hdfs/datanode
mkdir -p /data/slot1/lisa/hdfs/datanode
mkdir -p /data/slot2/lisa/hdfs/datanode
mkdir -p /data/slot3/lisa/hdfs/datanode
mkdir -p /data/slot4/lisa/hdfs/datanode
mkdir -p /data/slot5/lisa/hdfs/datanode
mkdir -p /data/slot6/lisa/hdfs/datanode
mkdir -p /data/slot7/lisa/hdfs/datanode
mkdir -p /data/slot8/lisa/hdfs/datanode
mkdir -p /data/slot9/lisa/hdfs/datanode
mkdir -p /data/slot11/lisa/hdfs/datanode
mkdir -p /data/slot10/lisa/hdfs/datanode
chown -R lisa:lisa /data/slot0/lisa
chown -R lisa:lisa /data/slot1/lisa
chown -R lisa:lisa /data/slot2/lisa
chown -R lisa:lisa /data/slot3/lisa
chown -R lisa:lisa /data/slot4/lisa
chown -R lisa:lisa /data/slot5/lisa
chown -R lisa:lisa /data/slot6/lisa
chown -R lisa:lisa /data/slot7/lisa
chown -R lisa:lisa /data/slot8/lisa
chown -R lisa:lisa /data/slot9/lisa
chown -R lisa:lisa /data/slot10/lisa
chown -R lisa:lisa /data/slot11/lisa
#!/bin/bash
ssh -t 10.149.11.153 'mkdir -p /data/slot0/lisa/hdfs/namenode'
ssh -t 10.149.11.153 'mkdir -p /data/slot0/lisa/hdfs/journalnode'
ssh -t 10.149.11.153 'mkdir -p /data/slot0/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot1/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot2/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot3/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot4/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot5/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot6/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot7/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot8/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot9/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot11/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'mkdir -p /data/slot10/lisa/hdfs/datanode'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot0/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot1/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot2/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot3/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot4/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot5/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot6/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot7/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot8/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot9/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot10/lisa'
ssh -t 10.149.11.153 'chown -R lisa:lisa /data/slot11/lisa'
ssh -t 10.149.11.154 'mkdir -p /data/slot0/lisa/hdfs/namenode'
ssh -t 10.149.11.154 'mkdir -p /data/slot0/lisa/hdfs/journalnode'
ssh -t 10.149.11.154 'mkdir -p /data/slot0/lisa/hdfs/datanode'
......
修改gen_remote_cmd.lsp代码如下:
#!/usr/bin/newlisp
(println "this util will help to generate commands on remote server using newlisp and ssh")
(println "example: " "./gen_remote_cmds.lsp remote-hosts.lsp your-cmd-file output_file.sh")
;; check file path exists or not
;; exit process if not exist and print err-msg
(define (check-file-exist file-path err-msg)
(unless (file? file-path)
(println (string file-path err-msg))
(exit 1)))
(set 'remote-hosts-file (main-args 2))
(check-file-exist remote-hosts-file " input arg file(remote-hosts.lsp) path does not exist")
;; this will set symbol remotes
(load remote-hosts-file)
(set 'cmd-file (main-args 3))
(check-file-exist cmd-file " input arg file path(your-cmd-file) does not exist")
(set 'output-file (main-args 4))
(if (file? output-file)
(delete-file output-file))
;; create output file
(append-file output-file "#!/bin/bash")
(append-file output-file "\n")
(exec (string "chmod +x " output-file))
(set' ssh-prefix "ssh -t ")
(set' cmds (read-file cmd-file))
(println "cmds: " cmds)
(set 'cmd-list '())
(set 'in-file (open cmd-file "read"))
(while (read-line in-file)
(push (current-line) cmd-list -1))
(close in-file)
(dolist (host remotes)
(dolist (cmd cmd-list)
(set 'cmd2 (string ssh-prefix host " '" cmd "'"))
(append-file output-file cmd2)
(append-file output-file "\n"))
)
(exit)
在使用过程中,发现如果只是通过ssh -t运行命令,会遇到环境变量没有加载的情况,比如/etc/profile中配置的hadoop需要的环境变量没有加载。因此采用下面的方式更好
ssh -t remote_host_name <<EOF
... #your command
... #your command
EOF
#!/usr/bin/newlisp
(println "this util will help to generate commands on remote server using newlisp and ssh")
(println "example: " "./gen_remote_cmds.lsp remote-hosts.lsp your-cmd-file output_file.sh")
;; check file path exists or not
;; exit process if not exist and print err-msg
(define (check-file-exist file-path err-msg)
(unless (file? file-path)
(println (string file-path err-msg))
(exit 1)))
(set 'remote-hosts-file (main-args 2))
(check-file-exist remote-hosts-file " input arg file(remote-hosts.lsp) path does not exist")
;; this will set symbol remotes
(load remote-hosts-file)
(set 'cmd-file (main-args 3))
(check-file-exist cmd-file " input arg file path(your-cmd-file) does not exist")
(set 'output-file (main-args 4))
(if (file? output-file)
(delete-file output-file))
;; create output file
(append-file output-file "#!/bin/bash")
(append-file output-file "\n")
(exec (string "chmod +x " output-file))
(set' ssh-prefix "ssh -t ")
(set' cmds (read-file cmd-file))
(println "cmds: " cmds)
(set 'cmd-list '())
(set 'in-file (open cmd-file "read"))
(while (read-line in-file)
(push (current-line) cmd-list -1))
(close in-file)
(dolist (host remotes)
(append-file output-file (string ssh-prefix host "<<EOF\n"))
(dolist (cmd cmd-list)
(append-file output-file cmd)
(append-file output-file "\n"))
(append-file output-file "exit\n")
(append-file output-file "EOF\n\n"))
(exit)