最近文章

useradd命令:新建用户

说明useradd命令有两个功能:新建用户以及修改新建用户的默认值。新建用户useradd命令如果没有-D选项,它会使用命令行指定的值加上系统的默认值来新建用户。它根据命令的选项可能会做:新建用户的主目录(一般建在/home/目录下,当然你也可以指定home目录的路径)给新用户创建一个组(group)修改新建用户的默认值useradd命令如果只使用了-D选项,那么它用来显示系统用于新建用户的默认值
标签:

id命令:显示用户和组的id

说明id命令是用来列出真实有效的用户uid以及组的gid。我们可以用它来查找某个用户的uid和gid。语法id [OPTION]... [USER] USER为指定查询的用户名,如果没有提供USER,默认会列出所有的用户的uid以及他们的组gid。选项-a: 忽略,这个参数是为了与其他版本的兼容性-Z,--context:只打印当前用户的安全上下文-g,--group
标签:

logname命令:显示登陆用户名

说明显示当前登录用户的用户名。语法logname [OPTION]选项--help:在线帮助;--vesion:显示版本信息。示例显示登陆用户名$logname demo
标签:

chpasswd命令:批量修改密码

说明chpasswd命令是以批量的模式更新用户的密码。它会从标准输入里读取账号和密码对列表,然后用这些信息更新用户的密码。其中账号密码对的格式为:username:password如果在文件里,一行一个账号密码对。语法chpasswd [options]选项-c Method:指定加密的方法,可用的方法包括:DES, MD5, NONE以及SHA256/SH
标签:

Ubuntu16.04/17.10使用gnome-tweak-tool修改主题(theme)

这里介绍介绍下如何使用gnome-tweak-tool修改Ubuntu 16/17的主题。安装gnome-tweak-tool使用apt安装gnome-tweak-tool:$ sudo apt update $ sudo apt install gnome-tweak-tool建议安装gnome-shell-exte
标签:

C++17 获取文件字节大小的方法

C++ 17可以使用filesystem来获取文件路径的字节大小:#include <cstdint> #include <filesystem> // ... std::uintmax_t size = std::filesystem::file_size("c:\\foo\\bar.txt");需要注意的是,除非是独自占有地打开文件来读,否在文件的字节大小会随着读的过程
标签:

newusers命令:批量添加用户

说明newusers命令提供了批量添加或更新用户的功能。它允许从文件或者标准输入读取用户信息,如果用户已存在则更新用户的信息,如果用户不存在则创建新用户。每行定义一个用户的信息,每行的格式需要严格按照/etc/passwd文件定义的格式。格式如下:pw_name:pw_passwd:pw_uid:pw_gid:pw_gecos:pw_dir:pw_shellpw_name:用户名pw_passwd
标签:

passwd命令:修改密码

说明修改用户的密码,以及设置密码的相关信息,包括密码过期时间,清空密码等等。语法passwd [-k] [-l] [-u [-f]] [-d] [-e] [-n mindays] [-x maxdays] [-w warndays] [-i inactived
标签:

chage命令:修改账号密码的过期信息

说明chage命令用来指定修改密码后密码的有效天数。 系统会根据此值来限定用户必须更改密码的日期。语法chage [options] LOGIN LOGIN:用户名选项-m days: 表示密码可更改的最小天数。-M days: 表示密码有效(可更改)的最大天数-E Date :表示在该日期之后密码失效,格式
标签:

userdel命令:删除用户

说明userdel命令用来删除指定的用户,以及与此用户相关的文件。默认只删除用户帐号,不删除相关文件。语法userdel [options] LOGIN LOGIN:被删除的用户名。选项-f:强制删除用户,即使用户当前已登录,但这是一个危险的操作,可能会导致系统的状态不一致。-r:删除用户的同时,删除与用户相关的所有文件。不指定此选项,默认只删除用户账号。相关文件/etc/gr
标签:

pwconv命令:转换密码到shadow文件

说明Linux新建用户和组的信息分别存放在/etc/passwd和/etc/group。这两个文件所有的用户都是可以查看的。/etc/passwd格式如下:$less /etc/passwd [clcaza@majing-web ~]$ less /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bi
标签:

在shell脚本使用sftp登陆远程服务执行命令

有时我们需要定期登陆到远程服务器去去执行一些命令,sftp是一个让我们在shell脚本登陆到远程服务器的工具,这里演示一个例子:echo "sftp start" >> ~/logfile.log sftp username@host <<EOF >> ~/logfile.log
标签:

Bash输出错误信息到标准错误stderr

首先要了解文件描述符:文件描述符 0:表示标准输入stdinput文件描述符 1:表示标准输出stdout文件描述符 2:表示标准错误stderr要把信息输出到标准错误,可以把stdout(文件描述符 1)重定向stderr(文件描述符 2),命令如下:>&2 echo "error" 其中echo "e
标签:

Linux使用scp拷贝多个文件到远程服务器

使用scp复制多个文件根据文件传输方向的不同,可以分为两种情况:远程服务器拷贝多个文件到本地本地上传多个文件到远程服务器1、远程服务器拷贝多个文件到本地$ scp username@remote.com:/from/path/\{a,b,c\} ./ 2、本地上传多个文件到远程服务器$ scp foo.txt bar.txt u
标签:

给Dockerfile传递外部参数

在Dockerfile文件里使用ARG获取外部参数。在if else条件里使用外部参数:FROM centos:7ARG argRUN if [ "x$arg" = "x" ] ; then echo Argument not provided ; else echo Argument is $arg ; fi构建image镜像:docker build -t docker_demo . &nbs
标签:

pwunconv:转换shadow密码到passwd

说明pwunconv命令的作用和pwconv命令相反,它会从passwd和shadow创建密码,最后会把shadow删除。语法pwunconv [options] 示例查看/etc/passwd$cat /etc/passwod | grep ca ca:x:500:500::/home/ca:/bin/bash 查看/etc/shadow$cat
标签:

C#对List的元素按属性排序

C#对List元素排序有几种方法。方法一、使用LinqList<User> sortedList = list.OrderBy(o=>o.ID).ToList();如果按降序排序,可以使用OrderByDescending方法:List<User> sortedList = list.OrderByDescending(o=>o.ID).ToList();方法二
标签:

docker-machine配置导入/导出脚本

为了在多个主机同步docker-machine的配置,常常需要对docker-machine配置进行导入导出。这里附上两个脚本分别用于导出/导入docker-machine配置:docker-machine-export.sh和docker-machine-import.sh。这两个脚本需要所有的主机系统有相同的$MACHINE_STORAGE_PATH/certs。用法如下:导出(主机 
标签:

useradd命令:新建用户

说明

useradd命令有两个功能:新建用户以及修改新建用户的默认值。

新建用户

useradd命令如果没有-D选项,它会使用命令行指定的值加上系统的默认值来新建用户。

它根据命令的选项可能会做:

  1. 新建用户的主目录(一般建在/home/目录下,当然你也可以指定home目录的路径)
  2. 给新用户创建一个组(group)

修改新建用户的默认值

useradd命令如果只使用了-D选项,那么它用来显示系统用于新建用户的默认值。如果使用-D以及其他选项,那么它会用来更新系统用于新建用户的默认值。

语法

useradd [options] LOGIN
useradd -D
useradd -D [options]

LOGIN:新建的用户名

选项

  • -b <根目录 >:系统默认的根目录,它用来创建用户的主目录,规则是根目录拼接上用户。只有-d <用户主目录>没有指定时才会用到此值。
  • -c <备注>:备注。备注文字会保存在passwd的备注栏位中;
  • -d <用户主目录>:指定用户的主目录;
  • -D:指示命令是用于显示或更改系统新建用户的默认值;
  • -e <失效日期>:指定帐号的失效日期,格式YYYY-MM-DD。默认为空,表示不过期。
  • -f <缓冲天数>:指定在密码过期后多少天即关闭该帐号;
  • -g <群组>:指定用户所属的群组;
  • -G <群组>:指定用户所属的附加群组;
  • -m:自动建立用户的主目录;
  • -M:不要自动建立用户的主目录;
  • -N:取消建立以用户名称为名的群组;
  • -r:建立系统帐号;
  • -s <shell>:指定用户登入后所使用的shell;
  • -u <uid>:指定用户id。

修改默认值选项

以下几个选项分别用于修改默认的根目录,失效日期,密码过期缓存日期,加入的群组以及使用的shell。

  • -b <根目录 >:系统默认的根目录,它用来创建用户的主目录,规则是根目录拼接上用户。只有-d <用户主目录>没有指定时才会用到此值。
  • -e <失效日期>:指定帐号的失效日期,格式YYYY-MM-DD。默认为空,表示不过期。
  • -f <缓冲天数>:指定在密码过期后多少天即关闭该帐号;
  • -g <群组>:指定用户所属的群组;
  • -s <shell>:指定用户登入后所使用的shell;

相关文件

  • 账号信息:/etc/passwd
  • 账号安全信息:/etc/shadow
  • 组信息:/etc/group
  • 组安全信息:/etc/gshadow
  • 创建用户默认信息:/etc/default/useradd

示例

新建用户指定组

useradd –g sales zhangsan –G company,employees    //-g:加入主要组、-G:加入次要组

id命令:显示用户和组的id

说明

id命令是用来列出真实有效的用户uid以及组的gid。我们可以用它来查找某个用户的uid和gid。

语法

id [OPTION]... [USER]

USER为指定查询的用户名,如果没有提供USER,默认会列出所有的用户的uid以及他们的组gid。

选项

  • -a: 忽略,这个参数是为了与其他版本的兼容性
  • -Z,--context:只打印当前用户的安全上下文
  • -g,--group:只打印有效的组ID
  • -G,--groups:打印所有的组【附加组】ID
  • -n,--name:打印名称而不是数字。适用于 -ugG
  • -r,--real:打印真实的ID替代有效的ID。  对-ugG 而言
  • -u,--user:只打印用户有效的ID

示例

$ id
uid=1000(ca) gid=1001(ca) groups=1001(ca),1000(admin)

logname命令:显示登陆用户名

说明

显示当前登录用户的用户名。

语法

logname [OPTION]

选项

  • --help:在线帮助;
  • --vesion:显示版本信息。

示例

显示登陆用户名

$logname
demo

chpasswd命令:批量修改密码

说明

chpasswd命令是以批量的模式更新用户的密码。它会从标准输入里读取账号和密码对列表,然后用这些信息更新用户的密码。

其中账号密码对的格式为:

username:password

如果在文件里,一行一个账号密码对。

语法

chpasswd [options]

选项

  • -c Method:指定加密的方法,可用的方法包括:DES, MD5, NONE以及SHA256/SHA512,前提是libc需要支持这些加密方法。
  • -e:直接提供已加密的密码。
  • -m:如果密码没有加密,则指定使用md5加密。

示例

1、使用管道重定向

$echo demo:123456 | chpasswd

使用echo输出demo:123456,然后重定向给chpasswd修改demo的密码为123456.

2、使用文件批量修改

$vim users.txt
zhangsan:123456
lisi:abcdef

首先使用vim按照账号密码对的格式录入账号密码,执行批量更新:

chpasswd < users.txt

Ubuntu16.04/17.10使用gnome-tweak-tool修改主题(theme)

这里介绍介绍下如何使用gnome-tweak-tool修改Ubuntu 16/17的主题。

安装gnome-tweak-tool

使用apt安装gnome-tweak-tool:

$ sudo apt update
$ sudo apt install gnome-tweak-tool

建议安装gnome-shell-extensions

$ sudo apt install gnome-shell-extensions

创建主题目录

创建存放主题和icon的目录:

$ mkdir -v ~/.{themes,icons}
mkdir: created directory '/home/vivek/.themes'
mkdir: created directory '/home/vivek/.icons'

安装主题

使用apt搜索主题,并安装:

$ apt search theme
$ apt search theme | grep arc
$ sudo apt install arc-theme

可以下载shell的主题:

$ cd ~/.themes/
$ cd /tmp/
$ wget https://github.com/daniruiz/Flat-Remix-GNOME-theme/archive/master.zip
$ unzip master.zip
$ mv flat-remix-gnome-master/Flat-Remix/ ~/.themes/
$ gsettings set org.gnome.shell.extensions.user-theme name "Flat-Remix"

修改Ubuntu 16.04/17.10的主题

启动gnome-tweak-tool来修改主题:

$ gnome-tweak-tool &

打开tweaks,按Appearance > Themes > Applications 选择修改的主题,如图:

启用shell主题

启用shell主题需要用到刚才安装的gnome-shell-extensions。启动gnome-tweak-tool:

$ gnome-tweak-tool &

按照Appearance > Themes > Application,选择shell

C++17 获取文件字节大小的方法

C++ 17可以使用filesystem来获取文件路径的字节大小:

#include <cstdint>
#include <filesystem>
// ...
std::uintmax_t size = std::filesystem::file_size("c:\\foo\\bar.txt");

需要注意的是,除非是独自占有地打开文件来读,否在文件的字节大小会随着读的过程而变化。

使用的细节可以参考文档:https://en.cppreference.com/w/cpp/filesystem/file_size

newusers命令:批量添加用户

说明

newusers命令提供了批量添加或更新用户的功能。它允许从文件或者标准输入读取用户信息,如果用户已存在则更新用户的信息,如果用户不存在则创建新用户。

每行定义一个用户的信息,每行的格式需要严格按照/etc/passwd文件定义的格式。格式如下:

pw_name:pw_passwd:pw_uid:pw_gid:pw_gecos:pw_dir:pw_shell
  • pw_name:用户名
  • pw_passwd:加密后的密码,可以使用x代替
  • pw_uid:用户的uid
  • pw_gid:用户所属主组的gid
  • pw_gecos:用户的GECOS属性
  • pw_dir:用户的主目录(home)
  • pw_shell:用户登录后默认的shell

语法

newusers [options] [file]

其中file是可选的,如果没有提供文件,则会从标准输入里读取

示例

新建文件users.txt,添加以下内容:

user0:x:520:520::/home/user0:/bin/bash
user1:x:520:520::/home/user1:/sbin/nologin
user2:x:520:520::/home/user2:/sbin/nologin

使用

$newusers users.txt

如果想查看系统支持的shell,可以使用chsh命令:

$ chsh --list
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin

nologin的shell是不能登陆到系统的,一般是系统用户。常用的有/bin/bash和/bin/sh

passwd命令:修改密码

说明

修改用户的密码,以及设置密码的相关信息,包括密码过期时间,清空密码等等。

语法

passwd [-k] [-l] [-u [-f]] [-d] [-e] [-n mindays] [-x maxdays] [-w warndays] [-i inactivedays] [-S] [--stdin] [username]

username是可选的,如果没有指定username,修改的是当前登录用户的密码。

选项

  • -d:删除密码。
  • -e:让密码马上失效。
  • -f:强制执行。
  • -k:只有密码过期后才允许修改。
  • -l :锁住账号,禁止用户使用此密码登陆。但是用户是可以使用其他方式,如密钥登陆。
  • -S:查询用户的密码状态,仅能root用户操作;
  • -u:解锁账号的密码
  • -x DAYS:两次密码修正的最大天数,后面接数字,仅能root权限操作
  • -n DAYS:两次密码修改的最小天数,后面接数字,仅能root权限操作
  • -w DAYS:在距多少天提醒用户修改密码,仅能root权限操作;
  • -i DAYS:在密码过期后多少天,用户被禁掉,仅能以root操作;

示例

1、修改用户自己的密码

$passwd

直接输入passwd命令,不指定用户名则是修改当前用户的密码。

2、修改指定用户的密码

修改指定用户的密码需要时root,或者是有sudo权限的用户。

$passwd demo

3、锁定账号密码

$passwd -l demo

锁定账号的密码后,除了root用户外,其他用户是不能修改此用户的秘密。

chage命令:修改账号密码的过期信息

说明

chage命令用来指定修改密码后密码的有效天数。 系统会根据此值来限定用户必须更改密码的日期。

语法

chage [options] LOGIN

LOGIN:用户名

选项

  • -m days: 表示密码可更改的最小天数。
  • -M days: 表示密码有效(可更改)的最大天数
  • -E Date :表示在该日期之后密码失效,格式YYYY-MM-DD
  • -l username: 可以查看用户的当前设置信息
  • -W days: 指定口令过期前要警告用户的天数。
  • -d:上一次更改的日期。

示例

/etc/login.defs配置密码过期的默认信息:

# Password aging controls:
#
#       PASS_MAX_DAYS   Maximum number of days a password may be used.
#       PASS_MIN_DAYS   Minimum number of days allowed between password changes.
#       PASS_MIN_LEN    Minimum acceptable password length.
#       PASS_WARN_AGE   Number of days warning given before a password expires.
#
PASS_MAX_DAYS   99999
PASS_MIN_DAYS   0
PASS_MIN_LEN    5
PASS_WARN_AGE   7

/etc/default/useradd的EXPIRE变量也可以设置密码过期的默认值。

# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

要求用户demo5天内不能更改口令,并且口令最长的有效期为30天,口令过期前5天通知用户:

$chage -m 5 -M 30 -W 5 user1

userdel命令:删除用户

说明

userdel命令用来删除指定的用户,以及与此用户相关的文件。默认只删除用户帐号,不删除相关文件。

语法

userdel [options] LOGIN

LOGIN:被删除的用户名。

选项

  • -f:强制删除用户,即使用户当前已登录,但这是一个危险的操作,可能会导致系统的状态不一致。
  • -r:删除用户的同时,删除与用户相关的所有文件。不指定此选项,默认只删除用户账号。

相关文件

  • /etc/group:组信息
  • /etc/login.defs:影子密码套件配置
  •  /etc/passwd:用户信息
  •  /etc/shadow:保护用户帐户信息。

示例

userdel demo //删除用户demo,但不删除他的主目录及文件;
userdel -r demo    //删除用户demo,并且删除他的主目录及目录下的文件;

pwconv命令:转换密码到shadow文件

说明

Linux新建用户和组的信息分别存放在/etc/passwd和/etc/group。这两个文件所有的用户都是可以查看的。

/etc/passwd格式如下:

$less /etc/passwd
[clcaza@majing-web ~]$ less /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
ca:x:1000:1001::/home/ca/bin/bash
nginx:x:997:995:nginx user:/var/cache/nginx:/sbin/nologin

冒号的第二个值为密码,你可以看到在密码的位置上是“x”。这是出于安全的考虑,为了避免密码泄露,加密后的密码是存放在/etc/shadow文件。

pwconv命令的作用就是把/etc/passwd里源码转换到/etc/shadow文件,并且使用"x"来替换。

语法

pwconv [options]

选项

 -h, --help:显示帮助信息

示例

$pwconv

把/etc/passwd的密码转换到/etc/shadow是在我们添加用户时,系统自动执行。

在shell脚本使用sftp登陆远程服务执行命令

有时我们需要定期登陆到远程服务器去去执行一些命令,sftp是一个让我们在shell脚本登陆到远程服务器的工具,这里演示一个例子:

echo "sftp start" >> ~/logfile.log

sftp username@host <<EOF >> ~/logfile.log
cd /to/path
rm *.csv
exit
EOF

exit_code=$?

if [[ $exit_code != 0 ]]; then
    echo "sftp error" >&2
    exit 1
fi

echo "sftp end" >> ~/logfile.log

其中exit_code接收了sftp登陆执行的返回码

Bash输出错误信息到标准错误stderr

首先要了解文件描述符:

  • 文件描述符 0:表示标准输入stdinput
  • 文件描述符 1:表示标准输出stdout
  • 文件描述符 2:表示标准错误stderr

要把信息输出到标准错误,可以把stdout(文件描述符 1)重定向stderr(文件描述符 2),命令如下:

>&2 echo "error"

其中echo "error"是输出到stdout,>&2是把输出重定向到stderr。

为了避免和其他重定向发生交互,可以使用subshell:

(>&2 echo "error")

也可以定义为一个函数,在调用:

echoerr() { echo "$@" 1>&2; }
echoerr "error"

更多详细可以参考:http://wiki.bash-hackers.org/howto/redirection_tutorial

Linux使用scp拷贝多个文件到远程服务器

使用scp复制多个文件根据文件传输方向的不同,可以分为两种情况:

  • 远程服务器拷贝多个文件到本地
  • 本地上传多个文件到远程服务器

1、远程服务器拷贝多个文件到本地

$ scp username@remote.com:/from/path/\{a,b,c\} ./

2、本地上传多个文件到远程服务器

$ scp foo.txt bar.txt username@remote.com:~
$ scp {foo,bar}.txt username@remote.com:~
$ scp *.txt username@remote.com:~

给Dockerfile传递外部参数

在Dockerfile文件里使用ARG获取外部参数。

在if else条件里使用外部参数:

FROM centos:7
ARG arg
RUN if [ "x$arg" = "x" ] ; then echo Argument not provided ; else echo Argument is $arg ; fi

构建image镜像:

docker build -t docker_demo .  --build-arg arg=45

或者:

docker build -t docker_demo . 

 

pwunconv:转换shadow密码到passwd

说明

pwunconv命令的作用和pwconv命令相反,它会从passwd和shadow创建密码,最后会把shadow删除。

语法

pwunconv [options]

示例

查看/etc/passwd

$cat /etc/passwod | grep ca
ca:x:500:500::/home/ca:/bin/bash

查看/etc/shadow

$cat /etc/shadow | grep ca
ca:$6$o80masGZ$GxxxxxJGrRyCaPQdy2hxxx5KhExxxxEIa6ueQLI60/:16768:0:99999:7:::

其中ca为用户名,ca冒号后为密码。在/etc/shadow文件里显示的是加密后的密码,而在/etc/passwd文件里使用了"x"替换密码。

执行pwunconv

$pwunconv

重新查看/etc/passwd

$cat /etc/passwod | grep ca
ca:$6$o80masGZ$GxxxxxJGrRyCaPQdy2hxxx5KhExxxxEIa6ueQLI60/:500:500::/home/ca:/bin/bash

在/etc/passwd的第一冒号后的x替换为了之前在/etc/shadow文件里的加密密码。

重新查看/etc/shadow

$ sudo cat /etc/shadow
cat: /etc/shadow: 没有那个文件或目录

可以看到/etc/shadow文件被删除了。

注意:这里只是为了演示,强烈不建议把密码存放在/etc/passwd文件里。

恢复密码到/etc/shadow,执行:

$pwconv

C#对List的元素按属性排序

C#对List元素排序有几种方法。

方法一、使用Linq

List<User> sortedList = list.OrderBy(o=>o.ID).ToList();

如果按降序排序,可以使用OrderByDescending方法:

List<User> sortedList = list.OrderByDescending(o=>o.ID).ToList();

方法二、扩展IComparable接口

示例:

public class User : IComparable<User>
{
public string ID;
public string Name;
public int CompareTo(User other)
{
if (null == other)
return 1;
return string.Compare(this.Id, other.Id);
}
}

定义好类后,使用List排序如下:

List<User> myList = ...
myList.Sort();

如果是除了按Id排序,还有按其他属性排序的需求,可以实现IComparer接口:

public sealed class UserByNameComparer : IComparer<User> 
{
public int Compare(User x, User y)
{
if (object.ReferenceEquals(x, y))
return 0;
else if (null == x)
return -1;
else if (null == y)
return 1;
else
return string.Compare(x.Name, y.Name);
}
}

使用:

List<User> myList = ...
myList.Sort(new UserByNameComparer());


docker-machine配置导入/导出脚本

为了在多个主机同步docker-machine的配置,常常需要对docker-machine配置进行导入导出。这里附上两个脚本分别用于导出/导入docker-machine配置:docker-machine-export.sh和docker-machine-import.sh。

这两个脚本需要所有的主机系统有相同的$MACHINE_STORAGE_PATH/certs。用法如下:

导出(主机 A)

$ docker-machine ls
NAME       ACTIVE   DRIVER         STATE     URL                            SWARM   DOCKER    ERRORS
dev        -        digitalocean   Running   tcp://example.com:2376                 v1.10.1

$ ./docker-machine-export.sh dev
Exported machine to dev.zip

$ ls
docker-machine-import.sh
docker-machine-export.sh
dev.zip

使用docker-machine-export导出,给它一个导出的文件名,最后它会导出配置到zip压缩包。

导入 (主机 B)

$ docker-machine ls
NAME       ACTIVE   DRIVER         STATE     URL                            SWARM   DOCKER    ERRORS

$ ./docker-machine-import.sh dev.zip
Exported machine to dev.zip

$ docker-machine ls
NAME       ACTIVE   DRIVER         STATE     URL                            SWARM   DOCKER    ERRORS
dev        -        digitalocean   Running   tcp://example.com:2376                 v1.10.1

导入在主机A的docker-machine的配置压缩包docker-machine-import.zip

脚本如下

docker-machine-export.sh

#! /bin/bash

if [ -z "$1" ]; then
  echo "Usage: machine-export.sh MACHINE_NAME"
  echo ""
  echo "Exports the specified docker-machine to a MACHINE_NAME.zip file"
  echo "Note: This script requires you to have the same \$MACHINE_STORAGE_PATH/certs available on all host systems"
  exit 0
fi

machine_name=$1

docker-machine status $machine_name 2>&1 > /dev/null
if [ $? -ne 0 ]; then
  echo "No such machine found"
  exit 1
fi

set -e

MACHINE_STORAGE_PATH="${MACHINE_STORAGE_PATH:-"$HOME/.docker/machine"}"
machine_path="$MACHINE_STORAGE_PATH/machines/$machine_name"
tmp_path="/tmp/machine-export-$(date +%s%3)"

# copy to /tmp and strip out $MACHINE_STORAGE_PATH
mkdir -p $tmp_path
cp -r "$machine_path" "$tmp_path"
perl -pi -e "s|$MACHINE_STORAGE_PATH|__MACHINE__STORAGE_PATH__|g" $tmp_path/$machine_name/config.json

# create zip
rm -f "$machine_name.zip"
zip -rj "$machine_name.zip" "$tmp_path/$machine_name" > /dev/null

echo "Exported machine to $machine_name.zip"

# cleanup
rm -rf $tmp_path

docker-machine-import.sh

#! /bin/bash

set -e

if [ -z "$1" ]; then
  echo "Usage: docker-machine-import.sh MACHINE_NAME.zip"
  echo ""
  echo "Imports an exported machine from a MACHINE_NAME.zip file"
  echo "Note: This script requires you to have the same \$MACHINE_STORAGE_PATH/certs available on all host systems"
  exit 0
fi

machine_archive="$1"
machine_name="${machine_archive/.zip/}"
MACHINE_STORAGE_PATH="${MACHINE_STORAGE_PATH:-"$HOME/.docker/machine"}"
machine_path="$MACHINE_STORAGE_PATH/machines/$machine_name"

if [ -d "$machine_path" ]; then
  echo "$machine_name already exists"
  exit 1
fi

rm -rf "$machine_name"
unzip "$machine_archive" -d "$machine_name" > /dev/null
perl -pi -e "s|__MACHINE__STORAGE_PATH__|$MACHINE_STORAGE_PATH|g" $machine_name/config.json
mv "$machine_name" "$MACHINE_STORAGE_PATH/machines"

echo "Imported $machine_name to docker-machine ($machine_path)"

参考:https://gist.github.com/schickling/2c48da462a7def0a577e