Linux:以非交互方式执行交互式命令
在Linux的使用过程中有很多需要交互式输入的命令,系统通过非交互式的形式运行,比如下面的这样:
1 2 3 4 5 6 |
[root@mysql1 ~]# mysql_config_editor set --login-path=you_must_enter_password --host=localhost --user=root --port=3306 --password Enter password: [root@mysql1 ~]# [root@mysql1 ~]# mysql_config_editor set --login-path=you_must_enter_password --host=localhost --user=root --port=3306 --password="some_password" mysql_config_editor: [ERROR] mysql_config_editor: option '--password' cannot take an argument [root@mysql1 ~]# |
可以看到,在MySQL创建login-path的时候,必须要交互式的写入口令,而不能传参。
在Linux中,输入重定向的常见方法有这么几个:
- EOF
- 【<】
先来看看EOF的情况:
1 2 3 4 5 |
[root@mysql1 ~]# mysql_config_editor set --login-path=you_must_enter_password_1 --host=localhost --user=root --port=3306 --password<<EOF Hey_Password EOF Enter password: [root@mysql1 ~]# |
可以看到,就算用了EOF,还是逃不开交互操作。
如果使用输入重定向会不会好点呢?来看看:
1 2 3 |
[root@mysql1 ~]# mysql_config_editor set --login-path=you_must_enter_password_2 --host=localhost --user=root --port=3306 --password < Password Enter password: [root@mysql1 ~]# |
结果看到了,也逃不掉交互式操作。
方式(一)
其实,在Linux中,要将以非交互式的方式执行上面这种场景中的交互式命令,可以使用命令:【expect】
具体如下:
首先,安装【expect】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
[root@mysql1 ~]# whereis expect expect:[root@mysql1 ~]# [root@mysql1 ~]# [root@mysql1 ~]# yum list | grep expect Repository mysql is listed more than once in the configuration expect.x86_64 5.45-14.el7_1 iso pexpect.noarch 2.3-11.el7 iso [root@mysql1 ~]# yum install -y expect Loaded plugins: langpacks, product-id, search-disabled-repos, subscription-manager This system is not registered with an entitlement server. You can use subscription-manager to register. Repository mysql is listed more than once in the configuration iso | 4.3 kB 00:00:00 mysql | 2.9 kB 00:00:00 Resolving Dependencies --> Running transaction check ---> Package expect.x86_64 0:5.45-14.el7_1 will be installed --> Processing Dependency: libtcl8.5.so()(64bit) for package: expect-5.45-14.el7_1.x86_64 --> Running transaction check ---> Package tcl.x86_64 1:8.5.13-8.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ===================================================================================================================================================================== Package Arch Version Repository Size ===================================================================================================================================================================== Installing: expect x86_64 5.45-14.el7_1 iso 262 k Installing for dependencies: tcl x86_64 1:8.5.13-8.el7 iso 1.9 M Transaction Summary ===================================================================================================================================================================== Install 1 Package (+1 Dependent package) Total download size: 2.1 M Installed size: 4.9 M Downloading packages: --------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 25 MB/s | 2.1 MB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : 1:tcl-8.5.13-8.el7.x86_64 1/2 Installing : expect-5.45-14.el7_1.x86_64 2/2 Verifying : 1:tcl-8.5.13-8.el7.x86_64 1/2 Verifying : expect-5.45-14.el7_1.x86_64 2/2 Installed: expect.x86_64 0:5.45-14.el7_1 Dependency Installed: tcl.x86_64 1:8.5.13-8.el7 Complete! [root@mysql1 ~]# [root@mysql1 ~]# whereis expect expect: /usr/bin/expect /usr/share/man/man1/expect.1.gz [root@mysql1 ~]# |
然后,使用【expect】:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[root@mysql1 ~]# cat do_expect.sh #!/usr/bin/expect set timeout -1 set loginpath "helloworld_1" spawn mysql_config_editor set --login-path=$loginpath --host=localhost --user=root --port=3306 --password expect "*password*" {send "你的口令\r"} interact [root@mysql1 ~]# [root@mysql1 ~]# chmod -R 755 do_expect.sh [root@mysql1 ~]# ls -ltr do_expect.sh -rwxr-xr-x 1 root root 219 Jul 22 02:52 do_expect.sh [root@mysql1 ~]# |
然后执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
[root@mysql1 ~]# mysql_config_editor print --all | grep '^\[' [mylogin] [login_as_root] [login_as_roots] [login_as_test] [by2] [] [abcd] [abcdef] [abcdegegef] [you_must_enter_password] [you_must_enter_password_1] [you_must_enter_password_2] [root@mysql1 ~]# [root@mysql1 ~]# ./do_expect.sh spawn mysql_config_editor set --login-path=helloworld_1 --host=localhost --user=root --port=3306 --password Enter password: [root@mysql1 ~]# [root@mysql1 ~]# mysql_config_editor print --all | grep '^\[' [mylogin] [login_as_root] [login_as_roots] [login_as_test] [by2] [] [abcd] [abcdef] [abcdegegef] [you_must_enter_password] [you_must_enter_password_1] [you_must_enter_password_2] [helloworld_1] [root@mysql1 ~]# |
可以看到,通过脚本,以非交互的模式,增加了一个login-path:【helloworld_1】
使用这个脚本添加的LOGIN-PATH,登录一下数据库,验证一下是不是真的可以使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[root@mysql1 ~]# mysql --login-path=helloworld_1 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 190 Server version: 5.7.25-28 Percona Server (GPL), Release 28, Revision c335905 Copyright (c) 2009-2019 Percona LLC and/or its affiliates Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> exit Bye [root@mysql1 ~]# |
可以看到,没有问题。
有时候这个过程中你可能遇到问题【spawn command no found】;
是因为你在使用【sh xxx】
在Linux中,使用【sh】执行某个脚本的时候,会忽略脚本文件第一行的【#!xxxx】的声明,而直接使用【/usr/bin/bash】解析脚本;
而上面的脚本中的【spawn】是【expect】的内置命令,故而【command not found】;
解法是:
- 赋予执行权限:chmod +x xxxxx
- 直接执行脚本:【./xxxxx】
方式(二)
还可以通过Python的模块【pexpect】,达成一样的效果。
具体如下:
首先,安装Python的【pexpect】模块:
执行前:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[root@mysql1 ~]# mysql_config_editor print --all | grep "^\[" [mylogin] [login_as_root] [login_as_roots] [login_as_test] [by2] [] [abcd] [abcdef] [abcdegegef] [you_must_enter_password] [you_must_enter_password_1] [you_must_enter_password_2] [helloworld_1] [python_1] [root@mysql1 ~]# |
执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[root@mysql1 1]# python Python 2.7.5 (default, Sep 12 2018, 05:31:16) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> >>> import pexpect; >>> >>> child = pexpect.spawn('mysql_config_editor set --login-path=python_2 --host=localhost --user=root --port=3306 --password') >>> child.expect('password') 0 >>> child.sendline('你的密码') 9 >>> |
然后,再看看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[root@mysql1 ~]# mysql_config_editor print --all | grep "^\[" [mylogin] [login_as_root] [login_as_roots] [login_as_test] [by2] [] [abcd] [abcdef] [abcdegegef] [you_must_enter_password] [you_must_enter_password_1] [you_must_enter_password_2] [helloworld_1] [python_1] [python_2] [root@mysql1 ~]# |
数据库登录试试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[root@mysql1 ~]# mysql --login-path=python_2 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 191 Server version: 5.7.25-28 Percona Server (GPL), Release 28, Revision c335905 Copyright (c) 2009-2019 Percona LLC and/or its affiliates Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> exit Bye [root@mysql1 ~]# |
可以看到,一样没有问题。
终了,…
1 thought on “Linux:以非交互方式执行交互式命令”