为什么有内测资格(红米note 7内测包4)但官方没给我

最近在Linux下用到数据库sqlite3,于是开始了该方面的学习。&0. 引言&我们这篇文章主要讲述了如何在C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理,&包括创建数据库、创建表格、插入数据、查询数据、删除数据等。&1. 说明&这里我们假设你已经编译好了sqlite的库文件 :&libsqlite3.a libsqlite3.la libsqlite3.so libsqlite3.so.0 libsqlite3.so.0.8.6 pkgconfig&和可执行文件 : sqlite3&我们再假设你的sqlite3的安装目录在 /usr/local/sqlite3 目录下。&如果不是,我们可以这样做,将你的安装文件复制到 /usr/local/sqlite3 这个目录,&这样我们好在下面的操作中更加统一,从而减少出错的概率&例如:[root@localhost home]# cp -rf sqlite-3.3.8-ix86/ /usr/local/sqlite3&这里假设 /home/sqlite-3.3.8-ix86/ 是你的安装目录,也就是说你的sqlite原来就是安装在这里&这样之后,我们的sqlite3的库文件目录是:/usr/local/sqlite3/lib&可执行文件 sqlite3 的目录是: /usr/local/sqlite3/bin&头文件 sqlite3.h 的目录是: /usr/local/sqlite3/include&现在开始我们的Linux下sqlite3编程之旅。&2. 开始&这里我们现在进行一个测试。&现在我们来写个C/C++程序,调用 sqlite 的 API 接口函数。&下面是一个C程序的例子,显示怎么使用 sqlite 的 C/C++ 接口. 数据库的名字由第一个参数取得且第二个参数或更多的参数是 SQL 执行语句. 这个函数调用sqlite3_open() 在 16 行打开数据库,并且sqlite3_close() 在 25 行关闭数据库连接。&[root@localhost temp]# vi opendbsqlite.c&按下 i 键切换到输入模式,输入下列代码:&// name: opendbsqlite.c&// This prog is used to test C/C++ API for sqlite3.It is very simple,ha!&// Author : zieckey All rights reserved.&// data : &#include &stdio.h&&#include &sqlite3.h&&int main( void )&{&sqlite3 *db=NULL;&char *zErrMsg = 0;&&//打开指定的数据库文件,如果不存在将创建一个同名的数据库文件&rc = sqlite3_open("zieckey.db", &db);&if( rc )&{&fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));&sqlite3_close(db);&exit(1);&}&else printf("You have opened a sqlite3 database named zieckey.db successfully!\nCongratulations! Have fun ! ^-^ \n");&sqlite3_close(db); //关闭数据库&return 0;&}&退出,保存。(代码输入完成后,按下 Esc 键,然后输入: :wq ,回车就好拉)&好拉,现在编译:[root@localhost temp]# gcc opendbsqlite.c -o db.out&或者遇到这样的问题:&[root@localhost temp]# gcc opendbsqlite.c -o db.out&opendbsqlite.c:11:21: sqlite3.h: 没有那个文件或目录&opendbsqlite.c: In function `main':&opendbsqlite.c:19: `sqlite3' undeclared (first use in this function)&opendbsqlite.c:19: (Each undeclared identifier is reported only once&opendbsqlite.c:19: for each function it appears in.)&opendbsqlite.c:19: `db' undeclared (first use in this function)&这是由于没有找到头文件的原因。&也许会碰到类似这样的问题:&[root@localhost temp]# gcc opendbsqlite.c -o db.out&/tmp/ccTkItnN.o(.text+0x2b): In function `main':&: undefined reference to `sqlite3_open'&/tmp/ccTkItnN.o(.text+0x45): In function `main':&: undefined reference to `sqlite3_errmsg'&/tmp/ccTkItnN.o(.text+0x67): In function `main':&: undefined reference to `sqlite3_close'&/tmp/ccTkItnN.o(.text+0x8f): In function `main':&: undefined reference to `sqlite3_close'&collect2: ld returned 1 exit status&这是个没有找到库文件的问题。&下面我们着手解决这些问题。&由于用到了用户自己的库文件,所用应该指明所用到的库,我们可以这样编译:&[root@localhost temp]# gcc opendbsqlite.c -o db.out -lsqlite3&我用用 -lsqlite3 选项就可以了(前面我们生成的库文件是 libsqlite3.so.0.8.6 等,&去掉前面的lib和后面的版本标志,就剩下 sqlite3 了所以是 -lsqlite3 )。&如果我们在编译安装的时候,选择了安装路径,例如这样的话:&.......&# ../sqlite/configure --prefix=/usr/local/sqlite3&# make&.......&这样编译安装时,sqlite的库文件将会生成在 /usr/local/sqlite3/lib 目录下&sqlite的头文件将会生成在 /usr/local/sqlite3/include 目录下&这时编译还要指定库文件路径,因为系统默认的路径没有包含 /usr/local/sqlite3/lib&[root@localhost temp]# gcc opendbsqlite.c -o db.out -lsqlite3 -L/usr/local/sqlite3/lib&如果还不行的话,可能还需要指定头文件 sqlite3.h 的路径,如下:&[root@localhost temp]# gcc opendbsqlite.c -o db.out -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include&这样编译应该就可以了 ,运行:&[root@localhost temp]# ./db.out&./db.out: error while loading shared libraries: libsqlite3.so.0: cannot open shared object file: No such file or directory&运行是也许会出现类似上面的错误。&这个问题因为刚刚编译的时候没有选择静态编译,那么按照默认的编译就动态编译的。&动态编译后,由于可执行文件在运行时要调用系统库文件,&那么沿着系统默认的库文件搜索路径搜索,就可能找不到我们现在所需的库文件。&致使出现 "error while loading shared libraries" 等错误。&我们可以这样解决:&方法一:静态编译&在编译时加上 -static 参数,例如&[root@localhost temp]# gcc opendbsqlite.c -o db.out -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include -static&[root@localhost temp]# ll&总用量 1584&-rwxr-xr-x 1 root root 月 13 10:50 db.out&-rw-r--r-- 1 root root 614 11月 13 10:31 opendbsqlite.c&可以看到输出文件 db.out ,其大小为: 1596988k&运行,好了,没有出现错误&[root@localhost temp]# ./db.out&You have opened a sqlite3 database named zieckey.db successfully!&Congratulations! Have fun ! ^-^&方法二:重新配置系统环境变量 LD_LIBRARY_PATH&这时需要指定 libsqlite3.so.0 库文件的路径,也就是配置系统环境变量 LD_LIBRARY_PATH ,&使系统能够找到 libsqlite3.so.0 。&去掉 -static ,在编译:&[root@localhost temp]# gcc opendbsqlite.c -o db.out -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include&[root@localhost temp]# ll&总用量 36&-rwxr-xr-x 1 root root 12716 11月 13 10:56 db.out&-rw-r--r-- 1 root root 614 11月 13 10:31 opendbsqlite.c&[root@localhost temp]#&可以看到输出文件 db.out ,其大小为: 12716k,比刚才的静态编译要小得多。&所以我们推荐使用动态编译的方法。&好了,现在我们来指定系统环境变量 LD_LIBRARY_PATH 的值&在shell下输入:&[root@localhost temp]# export LD_LIBRARY_PATH=/usr/local/sqlite3/lib:$LD_LIBRARY_PATH&再运行&[root@localhost temp]# ./db.out&You have opened a sqlite3 database named zieckey.db successfully!&Congratulations! Have fun ! ^-^&是不是很有成就感阿 ,呵呵,这个上手还是很快的。&3. 插入:insert&刚刚我们知道了怎么调用 sqlite3 的C/C++的API函数接口,下面我们看看怎么在C语言中向数据库插入数据。&好的,我们现编辑一段c代码,取名为 insert.c&// name: insert.c&// This prog is used to test C/C++ API for sqlite3 .It is very simple,ha !&// Author : zieckey All rights reserved.&// data : &#include &stdio.h&&#include &stdlib.h&&#include "sqlite3.h"&#define _DEBUG_&int main( void )&{&sqlite3 *db=NULL;&char *zErrMsg = 0;&&rc = sqlite3_open("zieckey.db", &db); //打开指定的数据库文件,如果不存在将创建一个同名的数据库文件&if( rc )&{&fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));&sqlite3_close(db);&exit(1);&}&else printf("You have opened a sqlite3 database named zieckey.db successfully!\nCongratulations! Have fun ! ^-^ \n");&//创建一个表,如果该表存在,则不创建,并给出提示信息,存储在 zErrMsg 中&char *sql = " CREATE TABLE SensorData(ID INTEGER PRIMARY KEY,SensorID INTEGER,SiteNum INTEGER,Time VARCHAR(12),SensorParameter REAL);" ;&sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );&#ifdef _DEBUG_&printf("%s\n",zErrMsg);&#endif&//插入数据&sql = "INSERT INTO \"SensorData\" VALUES( NULL , 1 , 1 , '', 18.9 );" ;&sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );&sql = "INSERT INTO \"SensorData\" VALUES( NULL , 1 , 1 , '', 16.4 );" ;&sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );&sqlite3_close(db); //关闭数据库&return 0;&}&好的,将上述代码写入一个文件,并将其命名为 insert.c 。&解释:&sqlite3_exec的函数原型说明如下:&int sqlite3_exec(&sqlite3*, /* An open database */&const char *sql, /* SQL to be executed */&sqlite_callback, /* Callback function */&void *, /* 1st argument to callback function */&char **errmsg /* Error msg written here */&);&编译:&[root@localhost temp]# gcc insert.c -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include&insert.c:28:21: warning: multi-line string literals are deprecated&[root@localhost temp]#&执行&[root@localhost temp]# ./a.out&./a.out: error while loading shared libraries: libsqlite3.so.0: cannot open shared object file: No such file or directory&[root@localhost temp]#&同样的情况,如上文处理方法:&[root@localhost temp]# export LD_LIBRARY_PATH=/usr/local/sqlite3/lib:$LD_LIBRARY_PATH&[root@localhost temp]# ./a.out&You have opened a sqlite3 database named zieckey.db successfully!&Congratulations! Have fun ! ^-^&(null)&(null)&(null)&[root@localhost temp]#&运行成功了,好了,现在我们来看看是否插入了数据&[root@localhost temp]# /usr/local/sqlite3/bin/sqlite3 zieckey.db&SQLite version 3.3.8&Enter ".help" for instructions&sqlite& select * from SensorD&1|1|1||18.9&2|1|1||16.4&sqlite&&哈哈,已经插入进去了,不是吗?&很简单是不?&4. 查询: SELETE&好了,我们知道了怎么调用 sqlite3 的C/C++的API函数接口去创建数据库、创建表格、并插入数据,&下面我们看看怎么在C语言中查询数据库中的数据。&好的,我们现编辑一段c代码,取名为 query.c&// name: query.c&// This prog is used to test C/C++ API for sqlite3 .It is very simple,ha !&// Author : zieckey All rights reserved.&// data : &#include &stdio.h&&#include &stdlib.h&&#include "sqlite3.h"&#define _DEBUG_&int main( void )&{&sqlite3 *db=NULL;&char *zErrMsg = 0;&&rc = sqlite3_open("zieckey.db", &db); //打开指定的数据库文件,如果不存在将创建一个同名的数据库文件&if( rc )&{&fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));&sqlite3_close(db);&exit(1);&}&else printf("You have opened a sqlite3 database named zieckey.db successfully!\nCongratulations! Have fun ! ^-^ \n");&//创建一个表,如果该表存在,则不创建,并给出提示信息,存储在 zErrMsg 中&char *sql = " CREATE TABLE SensorData( ID INTEGER PRIMARY KEY, SensorID INTEGER, SiteNum INTEGER, Time VARCHAR(12), SensorParameter REAL );" ;&sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );&#ifdef _DEBUG_&printf("zErrMsg = %s \n", zErrMsg);&#endif&//插入数据&sql = "INSERT INTO \"SensorData\" VALUES(NULL , 1 , 1 , '', 18.9 );" ;&sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );&sql = "INSERT INTO \"SensorData\" VALUES(NULL , 1 , 1 , '', 16.4 );" ;&sqlite3_exec( db , sql , 0 , 0 , &zErrMsg );&int nrow = 0, ncolumn = 0;&char **azR //二维数组存放结果&//查询数据&/*&int sqlite3_get_table(sqlite3*, const char *sql,char***result , int *nrow , int *ncolumn ,char **errmsg );&result中是以数组的形式存放你所查询的数据,首先是表名,再是数据。&nrow ,ncolumn分别为查询语句返回的结果集的行数,列数,没有查到结果时返回0&*/&sql = "SELECT * FROM SensorData ";&sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );&int i = 0 ;&printf( "row:%d column=%d \n" , nrow , ncolumn );&printf( "\nThe result of querying is : \n" );&for( i=0 ; i&( nrow + 1 ) * i++ )&printf( "azResult[%d] = %s\n", i , azResult[i] );&//释放掉 azResult 的内存空间&sqlite3_free_table( azResult );&#ifdef _DEBUG_&printf("zErrMsg = %s \n", zErrMsg);&#endif&sqlite3_close(db); //关闭数据库&return 0;&}&我们这里用到了一个查询的语句是 "SELECT * FROM SensorData " ,&在C语言中对应的函数接口是 sqlite3_get_table( db , sql , &azResult , &nrow , &ncolumn , &zErrMsg );&这个函数接口的解释在程序中已经注释。&下面我们编译运行下看看,&[root@localhost temp]# export LD_LIBRARY_PATH=/usr/local/sqlite3/lib:$LD_LIBRARY_PATH&[root@localhost temp]# gcc query.c -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include&query.c:29:21: warning: multi-line string literals are deprecated&[root@localhost temp]# ./a.out&You have opened a sqlite3 database named zieckey.db successfully!&Congratulations! Have fun ! ^-^&zErrMsg = (null)&row:2 column=5&The result of querying is :&azResult[0] = ID&azResult[1] = SensorID&azResult[2] = SiteNum&azResult[3] = Time&azResult[4] = SensorParameter&azResult[5] = 1&azResult[6] = 1&azResult[7] = 1&azResult[8] = &azResult[9] = 18.9&azResult[10] = 2&azResult[11] = 1&azResult[12] = 1&azResult[13] = &azResult[14] = 16.4&zErrMsg = (null)&这里我们可以看到,azResult 的前面 5 个数据正好是我们的表 SensorData 的列属性,&之后才是我们要查询的数据。所以我们的程序中才有 i&( nrow + 1 ) * ncolumn 的判断条件:&for( i=0 ; i&( nrow + 1 ) * i++ )&printf( "azResult[%d] = %s\n", i , azResult[i] );&输出中有 zErrMsg = (null) 这样的字句,这是 zErrMsg 保留的错误信息,&正如你所看到的,zErrMsg 为空,表明在执行过程中没有错误信息。&SQLite3.3.6在ARM2410上的移植&要将SQLite3.3.6移植到ARM2410开发板上,除了要有底层操作系统的支持外,还必须要有相应的交叉编译工具链。由于ARM2410开发板采用的是ARM-Linux作为底层操作系统,因此需要首先安装ARM-Linux工具链。&1.交叉编译环境建立:&拷贝cross-2.95.3.tar.bz2到/usr/local目录下并解压缩。&cp cross-2.95.3.tar.bz2 /usr/local/arm&tar &jxvf cross-2.95.3.tar.bz2&2.编译SQLite-3.3.6&(1)在/root下建立目录sqlite,拷贝sqlite-3.3.6.tar.gz到该目录同时解压缩。&tar &zxvf sqlite-3.3.6.tar.gz&(2)新建目录:&cd /sqlite-3.3.6&mkdir build&(3)修改配置文件&vi configure&修改以下几个部分:&# if&test "$cross_compiling" = "yes"; then&# { { echo "$as_me:$LINENO: error: unable to find a compiler for building build tools" &&5&#echo "$as_me: error: unable to find a compiler for building build tools" &&2;}&# { (exit 1); exit 1; }; }&# fi&#else&# test "$cross_compiling" = yes &&&# { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" &&5&#echo "$as_me: error: cannot check for file existence when cross compiling" &&2;}&# { (exit 1); exit 1; }; }&#else&# test "$cross_compiling" = yes &&&# { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" &&5&#echo "$as_me: error: cannot check for file existence when cross compiling" &&2;}&# { (exit 1); exit 1; }; }&进入目录build:&cd build&../ configure --disable-tcl --host=arm-linux&这样在build目录中就将生成Makefile和一个libtool脚本&(4)修改Makefile文件:&cd build&vi Makefile&将下面的这行&BCC = arm-linux-gcc -g -O2&改成:&BCC = gcc -g -O2&将下面的这行:&sqlite3$(TEXE): $(TOP)/src/shell.c .libs/libsqlite3.la sqlite3.h&改成:&sqlite3$(TEXE): $(TOP)/src/shell.c .libs/libsqlite3.a sqlite3.h&我们都是将sqlite放到arm-linux的硬件板子上运行,所以我们一般将其编译成静态链接的形式。&保存Makefile文件后退出。&(5)编译:&执行make命令即可完成编译。&编译完成后,在build目录下生成许多.o和.lo文件。但最重要的时文件sqlite3。&file sqlite3&sqlite3: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.0.0, dynamically linked (uses shared libs), not stripped&由此可知,此时生成的sqlite文件是还未strip过的。执行命令arm-linux-strip, 去掉其中的调试信息,这样文件将减少很多。&arm-linux-strip sqlite3&再次用file命令查看sqlite3的信息:&file sqlite3&sqlite3: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.0.0, dynamically linked (uses shared libs), stripped&这就是在开发板上可以直接运行的可执行文件。&通过nfs将这些文件下载到开发板上。&需要注意:&拷贝是需要加上 &arf选项,因为libsqlite3.so,libsqlite3.so.0是链接到libsqlite3.so.0.8.6的。&cp &arf libsqlite3.so libsqlite3.so.0. libsqlite3.so.0.8.6 /usr/lib&cp sqlite3 /mnt/nfs&(6)测试结果:&chmod 777 sqlite3&编辑测试程序:test.c&编译:arm-linux-gcc test.c -L.libs -lsqlite3 &static&arm-linux-strip a.out&将其下载到开发板上:&执行:a.out ex "select * from tbl" &
阅读(...) 评论()linux下3种命令行交互方式(转)
Linux的脚本中自动登陆远程主机方法汇总
为了方面,我写了个脚本自动ssh登录远端机器,如下,这个脚本需要安装expect包
--------------------------------------------------------------------------------
================================
#!/usr/bin/expect
set timeout 60
spawn ssh root@192.168.0.101 -p 22 "/home/user/test.sh"
expect "password:"
send "******\r"
================================
set timeout 60
设置超时时间的,计时单位:秒
spawn ssh root@192.168.0.101
spawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。所以不要用
“which spawn“之类的命令去找spawn命令。它主要的功能是给ssh运行进程加个壳,用来传递交互指令
"/home/user/test.sh" 远程登陆后要执行的程序
expect "password:"
这里的expect也是expect的一个内部命令,expect的shell命令和内部命令是一样的,但不是一个功能。这个命令的意思是判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间后返回,这里等待时长就是前面设置的60秒
send "********\r"
这里就是执行交互动作,与手工输入密码的动作等效,如:1234456
温馨提示: 命令字符串结尾别忘记加上 “\r”,如果出现异常等待的状态可以核查一下。
执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上。如果你只是登录过去执行一段命令就退出,可改为〔expect
注意:在crontab里执行expect脚本,那么最后一句就不能是interact,应该是expect eof
参考:http://my.unix-center.net/~xiaoshe/tag/expectcrontabmysql定期备份数据库/
如下为网上转载的其他的shell自动交互的方法
--------------------------------------------------------------------------------
src:/art/898.htm
你了解Linux系统么?你是Linux系统的应用者么?如果你要学习linux,你可能会遇到Linux
Shell自动交互问题,这里将介绍Linux Shell自动交互的解决方法,在这里拿出来和大家分享一下。
shell脚本在处理自动循环或大的任务方面可节省大量的时间,通过创建一个处理任务的命令清单,使用变量、条件、算术和循环等方法快速创建脚本以完成相应工作,这比在命令行下一个个敲入命令要省时省力得多。
但是有时候我们可能会需要实现和交互程序如ftp,telnet服务器等进行交互的功能,这时候我们需要用到shell的自动交互功能,本文收集了较常用的三种自动交互方法,并进行了比较和总结。
从一台Linux机器ftp登陆到另一台Linux机器,进行系列操作后关闭,懒得每次都手动输入密码。
改变登录用户密码,懒得每次都输入新旧密码。
希望su自动登录到root账户,懒得每次都输入root密码。
三、调试环境
终端:SecureCRT
系统:WinXP, CentOS 4.4(VmWare)
Shell:bash
注:shell有很多种,B类SHELL(sh, bash, ksh)之间行为相近;C类SHELL(csh,
tcsh)之间行为相近,还有zsh和rc等shell,本文的调试环境是bash。
四、自动交互方法一
自动交互最关键的就是交互信息的自动输入,首先联想到文件重定向,在shell编程中有这样一种用法(参考Linux与UNIX
SHELL编程指南 chapt 5.7):"command && delimiter
从标准输入中读入,直至遇到delimiter分界符。"
重定向操作符command &&
delimiter是一种非常有用的命令,shell将分界符delimiter之后直至下一个同样的分界符之前的所有内容都作为输入,遇到下一个分界符,
shell就知道输入结束了。最常见的delimiter分界符是EOF,当然完全可以自定为其他字符。
对于需求1 要求的自动登陆ftp,并作系列操作,则可以用这种方法进行自动交互。代码如下:
1. #!/bin/bash
2. ftp -i -n 192.168.167.187 && EOF
3. user hzc 123456
5. cd test
测试可以发现,如上代码使用帐号名hzc,密码123456成功登陆了ftp服务器,并进入目录,打印出了pwd。
五、自动交互方法二
需求2中要求采用非交互的方式改变登录用户密码,尝试用方法1,无法实现。
这时候联想到交互信息的另一个自动输入方法,管道,通过echo + sleep + | 可以实现这个需求。
1. #!/bin/bash
2. (echo "curpassword"
3. sleep 1
4. echo "newpassword"
5. sleep 1
6. echo "newpassword")|passwd
测试通过,运行这个脚本,直接把当前用户的curpassword改成newpassword。
六、自动交互方法三
需求3中要求自动登录root账号,尝试方法1和方法2,都出现错误提示standard in must be a tty。
这时候尝试寻找外部帮助,一个shell工具expect可以实现这个功能,其实expect就是一个专门用来实现自动交互功能的工具,expect的语法可以参考相关资料,代码如下:
1. #!/usr/bin/expect
2. spawn su root
3. expect "password: "
4. send "123456\r"
5. expect eof
测试通过,运行这个脚本,直接从当前用户登录到root用户。
七、方法总结
方法一(重定向)简单直观,也经常有实际应用,但是在自动交互领域功能有限。
方法二(管道)也很简单直观,有时甚至不用sleep配合就能展现强大的自动交互实力,但是在某些时候也束手无策。
方法三(expect)在功能上是最为强大的,expect本来就是为实现自动交互功能而生,但是缺点是需要安装expect包,在嵌入式等环境下难以安装。
三个方法各有优劣,应用的好,都可以完成Linux Shell自动交互。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。本帖子已过去太久远了,不再提供回复功能。}

我要回帖

更多关于 红米note 7内测包 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信