centos7下让zookeeper开机自启动

 centos  centos7下让zookeeper开机自启动已关闭评论
5月 202020
 

centos 7下zookeeper开机自启动

1将ZooKeeper设置为开机启动
1.1在init.d目录下新建脚本文件
进入到/etc/rc.d/init.d目录下,命令是:

cd    /etc/rc.d/init.d

新建一个名为zookeeper的文件,命令是:

touch    zookeeper

 

1.1.1文件内容的第一种方案(推荐)
使用vim命令修改文件内容,文件内容的写法有很多,除了上面的第一种方案,用下面的这种也可以:

#!/bin/bash
#chkconfig: 2345 10 90
#description: service zookeeper
export JAVA_HOME=/opt/java/jdk1.8.0_121
export ZOO_LOG_DIR=/opt/zookeeper/log
ZOOKEEPER_HOME=/opt/zookeeper/zookeeper-3.4.10
su root ${ZOOKEEPER_HOME}/bin/zkServer.sh “$1”

3.1.2文件内容的第二种方案
使用vim命令修改文件内容,文件内容是:

#!/bin/bash
#chkconfig: 2345 10 90
#description: service zookeeper
export JAVA_HOME=/opt/java/jdk1.8.0_121
export ZOO_LOG_DIR=/opt/zookeeper/log
ZOOKEEPER_HOME=/opt/zookeeper/zookeeper-3.4.10
case “$1” in
start) su root ${ZOOKEEPER_HOME}/bin/zkServer.sh start;;
start-foreground) su root ${ZOOKEEPER_HOME}/bin/zkServer.sh start-foreground;;
stop) su root ${ZOOKEEPER_HOME}/bin/zkServer.sh stop;;
status) su root ${ZOOKEEPER_HOME}/bin/zkServer.sh status;;
restart) su root ${ZOOKEEPER_HOME}/bin/zkServer.sh restart;;
upgrade)su root ${ZOOKEEPER_HOME}/bin/zkServer.sh upgrade;;
print-cmd)su root ${ZOOKEEPER_HOME}/bin/zkServer.sh print-cmd;;
*) echo “requirestart|start-foreground|stop|status|restart|print-cmd”;;
esac

1.1.3 其他说明
注意1:新建文件的命令是touch,编辑文件的命令用vi和vim都行。如果不会使用vi和vim命令,直接在本地把文件编辑好,然后用远程工具上载上去都行,不过需要注意的是如果本地用的windows系统,需要把文件转为UNIX格式。转换工具有很多,例如使用Notepad++

注意2:两个方案中的文件头部#注释的部分不能少,而且文件中诸如JDK路径,zookeeper路径都需要修改为你自己的。

1.2 执行一系列命令
为新建的/etc/rc.d/init.d/zookeeper文件添加可执行权限,命令是:

chmod  +x  /etc/rc.d/init.d/zookeeper

把zookeeper这个脚本添加到开机启动项里面,命令是:

chkconfig  –add   zookeeper

 

如果想看看是否添加成功,命令是:

chkconfig  –list

 

1.3执行测试看是否开机启动
使用命令重启机器,命令是:

reboot

方法一

查看zookeeper的状态

重启机器,然后不手动启动zookeeper的情况下,执行命令:

service  zookeeper   status

 

方法二

查看2181端口是否启用,执行命令:

lsof  -i:2181

 

方法三

查看网络状态,执行命令:

netstat   -lntup

 

 

2报错及解决
2.1 service zookeeper does not support chkconfig
执行chkconfig  –add  zookeeper报错:

servicezookeeper does not support chkconfig

问题原因和解决:

/etc/rc.d/init.d/ zookeeper脚本中头部没有添加下面这几句话(description可以随便写):

#!/bin/bash
#chkconfig:2345 10 90
#description:service zookeeper

2.2Error contacting service. It is probably not running
执行service  zookeeper  status报错:

JMX enabled by default

Usingconfig: /opt/zookeeper/zookeeper-3.4.10/bin/../conf/zoo.cfg

Errorcontacting service. It is probably not running.

 

问题原因和解决:

/etc/rc.d/init.d/ zookeeper没有配置对,请看3.1.1和3.1.2的配置,里面必须要有export  JAVA_HOME这一句话,后面的路径是你自己的JDK安装路径。

至于export    ZOO_LOG_DIR=/opt/zookeeper/log这一句的话可有可无,意思是指定zookeeper的启动日志存放目录,如果该目录不存在,你必须手动创建一个。

 

原文链接:https://blog.csdn.net/pucao_cug/java/article/details/71240246

ubuntu下建立nginx自启动服务

 nginx  ubuntu下建立nginx自启动服务已关闭评论
5月 182020
 
一、Nignx中添加服务在服务目录中,/lib/systemd/system
1、 新建一个nginxd.service
[Unit]
Description=nginx
After=network.target
 
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload -c /usr/local/nginx/conf/nginx.conf
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
 
[Install]
WantedBy=multi-user.target

ExecStart:这句话的作用是 在/usr/local/nginx/sbin/nginx 中查找 nginx.conf 文件。

ExecReload:在/usr/local/nginx/sbin/nginx 中查找 nginx.conf 文件,刷新Nginx配置后重启。

ExecStop :在/usr/local/nginx/sbin/nginx 中停止nginx。

2、修改nginxd.service的权限

可执行权限chmod 755 nginxd.service 现在,在任何路径下 ,都可以直接使用nginx服务了。

systemctl daemon-reload :重载服务

systemctl status nginxd :查看 nginxd服务状态

systemctl restart nginxd.service :重启nginx服务

注意

1、systemctl status nginxd 中 nginxd 写成 nginxd.service 也可以。

2、如果不能够在windos中访问,参见【二、防火墙状态】,即关闭防火墙 或者在防火墙文件中配置这个端口。

二、防火墙状态

如果我们把防火墙停掉: systemctl stop iptables,那么任何外部的机器都能直接来访问服务器,而服务器也可以没有任何限制的去访问外部资源。相当于,防火墙是一个屏障,现在没有这个屏障了,双方可以互相沟通。

注意:systemctl disable iptables : 防火墙 永久不跟随系统启动而启动。即开机不自启动

systemctl start iptables : 启动防火墙

systemctl status iptables :查看防火墙状态

systemctl stop iptables : 停止防火墙 或者我们不关闭防火墙,那就需要我们在防火墙中把Nginx配置的端口打开。

防火墙默认地址:/etc/sysconfig/iptables在这个文件中添加这句话

-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

 

参考: https://www.jianshu.com/p/8a94a12b37bc

springboot jar包解压、重新压缩打包方法

 jar, spring-boot  springboot jar包解压、重新压缩打包方法已关闭评论
5月 112020
 

springboot在产生jar包后,有时需要修改其中的文件并重新打包,比如上传到服务器后,发现配置文件里某个配置没改,可以使用下面的方法:

以一个测试springboot 包  spingboot-ouu-test.jar 为例

因为有重新打包的需求,建议jar包放在一个空的文件夹下执行下面的命令:

  • 解压spingboot-ouu-test.jar

jar -xvf spingboot-ouu-test.jar

常见的配置文件如:application.properties在BOOT-INF/classes/目录下.

  • 修改文件后, 重新打包spingboot-ouu-test.jar,

jar  -cvfM0 spingboot-ouu-test.jar .           //(M后面是数字0,如果只使用参数cf,java -jar spingboot-ouu-test.jar启动springboot jar项目时将提示“没有主清单属性”)

 

附:

jar -tvf spingboot-ouu-test.jar   //查看jar包文件结构

jar命令常用参数:

c :创建一个 jar 包
t :显示 jar 包里面的内容
x :解压 jar 包
u :添加文件到 jar包
f :指定 jar 包的文件名
v :在 CMD 显示详细执行过程(报告)
m :指定 manufest.mf 文件(该文件可以对jar包及其内容做设置)
0 :打包 jar包 时不压缩
M :不产生 manufest.mf 文件,覆盖 m 参数的设置
i :为打包的 jar包 创建索引文件
c :进入某目录后再执行 jar 命令,相当于 cd 进入目录然后不带 c 参数执行 jar命令

 

python 2中希望使用print时将\uxxxx的文字打印为中文

 python  python 2中希望使用print时将\uxxxx的文字打印为中文已关闭评论
5月 092020
 

在python 2里使用print打印含有\uxxx的中文字符时不能直接显示中文,可以使用下面的方式:

举例:

obj = [u’\u53c8\u6765\u5077\u5077\u770b\u6211′,u’\u7231\u6211\u4f60\u5c31\u544a\u8bc9\u6211′]

使用: print(repr(obj).decode(‘unicode-escape’))

 

obj=[‘又来偷偷看我’,’爱我你就告诉我’]

使用:print(repr(obj).decode(‘string-escape’))

 

python 3 没有这个问题

Nginx配置basic_auth密码验证

 nginx  Nginx配置basic_auth密码验证已关闭评论
4月 292020
 

网上找到的一篇文章描述nginx配置basic_auth的,来自以下链接https://www.centos.bz/2017/07/nginx-basic_auth-password/

 

Nginx添加basic_auth,意思就是访问页面的时候需要弹出来一个用户和密码验证的东西,本文基于CentOS 6

1. 安装密码生成工具htpasswd并生成用户密码文件

yum install httpd-tools               #适用centos
sudo apt-get install apache2-utils    #适用ubuntu

生成用户密码文件

$ htpasswd -c /export/servers/.htpasswd user1  #回车会要求输入两遍密码,会清除所有用户!
$ htpasswd -bc /export/servers/.htpasswd user1 password  #不用回车,直接指定user1的密码为password
$ htpasswd -b /export/servers/.htpasswd user2 password   #添加一个用户,如果用户已存在,则是修改密码
$ htpasswd -D /export/servers/.htpasswd user2  #删除用户

2. 为Nginx添加basic_auth配置

server {
    listen        80;
#    root        /tmp;
#    index        index.html index.htm;
    server_name    o-u-u.com;

    location / {
        auth_basic        "input you user name and password";
        auth_basic_user_file    /export/servers/.htpasswd;
        proxy_pass http://127.0.0.1:9000;
    }
}

然后再次访问o-u-u.com时便会弹出验证框要求输入用户名和密码。

3. 可能遇到的问题

访问o-u-u.com没有弹出验证框怎么办?
首先修改nginx.conf,将日志级别调为info,如下

$ cat /export/servers/nginx-1.12.1/conf/nginx.conf
.......
user  admin;
worker_processes  8;

error_log  logs/error.log info;
......

然后再次访问让其产error_log
看到error_log时会发现有如下错误产生

*69 no user/password was provided for basic authentication, client: 10.12.138.126, server: www.zhukun.net, request: "GET /date_lateral HTTP/1.1", host: "www.zhukun.net"

原因在于

The HTTP Basic authentication works as following:
*) A browser requests a page without user/password.
*) A server response with 401 page, sending realm as well.
   At this stage the 401 code appears in access_log and the message
   “no user/password …” appears in error_log.
*) The browser shows a realm/login/password prompt.
*) If a user will press cancel, then the browser will show the received
   401 page.
*) If the user enters login/password, then the browser repeats the request
   with login/password.

Then until you will exit the browser, it will send these login/password
with all requests in protected hierarchy.

error_page配置的401页面不存在或者指向问题导致的,可以注释掉401配置或者保证401配置指向的文件可用,然后basic_auth便会生效。

linux下使用自己安装的oracle JDK替换默认的OpenJDK

 java  linux下使用自己安装的oracle JDK替换默认的OpenJDK已关闭评论
4月 272020
 

在linux系统中,由于涉及到版权问题,在大部分linux系统的发行版本中,默认都安装了OpenJDK,并且OpenJDK的java命令也已经加入到环境变量中了。

在刚装好的linux系统中,运行java -version,输出如下(根据JDK版本不同,输出的版本可能不同):

java version “1.7.0_131”
OpenJDK Runtime Environment (rhel-2.6.9.0.el6_8-x86_64 u131-b00)

但在进行java开发时,我们大多是需要使用Sun(准确的说应该是Oracle)的JDK,所以我们会去Oracle官网下载相应版本的JDK进行安装。

如何在linux上安装,在此不在赘述。

在linux上安装完JDK后,我们会在~/.bash_profile 把安装的java加入到环境变量中。原以为就万事大吉了,在运行java程序时会使用自己安装的JDK。

如果你是这么想的就大错特错了,在文章开头讲的,由于linux系统的发行版中默认安装的时OpenJDK,尽管我们把安装的SunJDK的java命令也加入到环境变量中,但是我们运行

java -version,输出确还是和之前一样:

java version “1.7.0_131”
OpenJDK Runtime Environment (rhel-2.6.9.0.el6_8-x86_64 u131-b00)

这要这么破!!!

一、查找原因

不急,先运行

whereis java,输出如下:
java: /usr/bin/java /etc/java /usr/lib/java /usr/share/java /opt/java/bin/java

在几个地方有java命令,其中/opt/java/bin/java是我自己安装的SunJDK的java命令所在的目录,而/usr/bin/java是系统中默认安装的java命令所在的目录。

原因就在这,

我们执行

ls -la /usr/bin/java,输入如下:

lrwxrwxrwx 1 root root 22 May 14 16:53 /usr/bin/java -> /etc/alternatives/java

一看这是一个软连接,我们cd到/etc/alternatives目录下看个究竟,

然后执行 ls -la,输入比较多,而且很多软链,其中有一个

lrwxrwxrwx  1 root root   46 May 14 18:22 java -> /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java

到此,应该明白了,java命令其实指向的是OpenJDK中的java命令,所以才会出现我们把自己安装的SunJDK的java命令配置到环境变量中后,依然不起作用。

所以我们要做的就是需要把java的软链指向我们自己安装的SunJDK的java命令,也即/opt/java/bin/java。

二、使用安装的JDK替代系统默认的OpenJDK

linux中提供了update-alternatives命令,update-alternatives是linux系统(大部分linux系统都支持此命令)中专门维护系统命令链接符的工具,通过它可以很方便的设置系统默认使用哪个命令、哪个软件版本,而所有的这些就构成了备选方案系统(alternatives system)。

很多时候我们会将拥有相同或相似功能的不同应用程序安装在同一个操作系统上,例如同一个操作系统上的不同文本编辑器。这给了这个系统的用户在编辑文本时有了更多的选择,如果用户愿意他们可以自由选择任意一个来使用。

其实update-alternatives命令的功能很好理解,举个例子:在Window系统中,如果我们安装多个浏览器,比如有火狐、有IE、有360、有Chrome等,当我们从某个链接进去打开网页时,可能会问你使用哪个浏览器,当你选择某个浏览器时,此浏览器会问你是否把它作为默认浏览器,如果你选择了是,那下次点开某个链接时,就直接使用默认浏览器打开了!

现在我们在系统中同时安装了open jdk和sun jdk两个版本,(由于linux发行版本中默认使用OpenJDK的java命令 )而我们又希望系统默认使用的是sun jdk,那怎么办呢?通过update-alternatives就可以很方便的实现了。

首先运行以下命令查看java当前的默认配置

update-alternatives –display java,输出如下(后面有省略):
java – status is manual.
link currently points to /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
/usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java – priority 170131
slave keytool: /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/keytool
slave orbd: /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/orbd
……

可以从输出中看到系统中java默认使用的OpenJDK,其中数字170131表示优先级。

2.1 下面进入正式配置阶段

1. 把自己安装的SunJDK加入到备选系统中

运行命令(注意命令最后的数字表示优先级,其中170130 为SunJDK的alternative的优先级)

update-alternatives  –install /usr/bin/java java /opt/java/bin/java 170130

2. 选择自己安装的SunJDK作为首选java命令

运行命令

update-alternatives –config java,输出如下

There are 2 programs which provide ‘java’.

Selection    Command
———————————————–
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
2           /opt/java/bin/java

Enter to keep the current selection[+], or type selection number:

config命令是交互式的命令,可以根据提示进行选择,此处我们选择2,即使用安装的SunJDK的java命令,然后按回车键!

至此,配置完成了!

说明:在配置步骤1中,我们指定SunJDK的优先级是170130(比当前优先级170131低),所以需要进行步骤二进行手动选择;如果我们指定的优先级比当前优先级170131高,则步骤二可以省略,系统自动会选择优先级高的作为默认alternative!

关于update-alternatives命令更详细的说明,请参照

1.http://www.cnblogs.com/pengdonglin137/p/3462492.html

2. http://www.mamicode.com/info-detail-1144825.html

3. http://persevere.iteye.com/blog/1479524

原文链接:https://blog.csdn.net/rj042/java/article/details/72034650

mybatis中#和$的区别

 mybatis, 开发  mybatis中#和$的区别已关闭评论
4月 232020
 

mybatis写sql语句时会看到#{}, ${}的写法,有什么区别呢?

1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。

2. $将传入的数据直接显示生成在sql中。如:select * from ${table};

3. #方式能够很大程度防止sql注入。

4.$方式无法防止Sql注入。

5.$方式一般用于传入数据库对象,例如传入表名,order by、like 语句只能用${}了,用#{}会多个’ ‘导致sql语句失效

6.一般能用#的就别用$.

mybatis下limit有参数计算时的写法

 开发  mybatis下limit有参数计算时的写法已关闭评论
4月 232020
 

mybatis下limit如果想做分页,对limit做参数计算时:

错误的写法:

<select id=”queryMyApplicationRecord” parameterType=”MyApplicationRequest” resultMap=”myApplicationMap”>
SELECT
a.*,
FROM
tb_user a
WHERE 1=1
<if test=”ids != null and ids.size()!=0″>
AND a.id IN
<foreach collection=”ids” item=”id” index=”index”
open=”(” close=”)” separator=”,”>
#{id}
</foreach>
</if>
<if test=”statusList != null and statusList.size()!=0″>
AND a.status IN
<foreach collection=”statusList” item=”status” index=”index”
open=”(” close=”)” separator=”,”>
#{status}
</foreach>
</if>
ORDER BY a.create_time desc
LIMIT (#{pageNo}-1)*#{pageSize},#{pageSize}; // 错误
</select>
在MyBatis中LIMIT之后的语句不允许的变量不允许进行算数运算,会报错。

正确的写法一:
<select id=”queryMyApplicationRecord” parameterType=”MyApplicationRequest” resultMap=”myApplicationMap”>
SELECT
a.*,
FROM
tb_user a
WHERE 1=1
<if test=”ids != null and ids.size()!=0″>
AND a.id IN
<foreach collection=”ids” item=”id” index=”index”
open=”(” close=”)” separator=”,”>
#{id}
</foreach>
</if>
<if test=”statusList != null and statusList.size()!=0″>
AND a.status IN
<foreach collection=”statusList” item=”status” index=”index”
open=”(” close=”)” separator=”,”>
#{status}
</foreach>
</if>
ORDER BY a.create_time desc
LIMIT ${(pageNo-1)*pageSize},${pageSize}; (正确)
</select>
正确的写法二:(推荐)
<select id=”queryMyApplicationRecord” parameterType=”MyApplicationRequest” resultMap=”myApplicationMap”>
SELECT
a.*,
FROM
tb_user a
WHERE 1=1
<if test=”ids != null and ids.size()!=0″>
AND a.id IN
<foreach collection=”ids” item=”id” index=”index”
open=”(” close=”)” separator=”,”>
#{id}
</foreach>
</if>
<if test=”statusList != null and statusList.size()!=0″>
AND a.status IN
<foreach collection=”statusList” item=”status” index=”index”
open=”(” close=”)” separator=”,”>
#{status}
</foreach>
</if>
ORDER BY a.create_time desc
LIMIT #{offSet},#{limit}; (推荐,代码层可控)
</select>
分析:方法二的写法,需要再请求参数中额外设置两个get函数,如下:
@Data
public class QueryParameterVO {

private List<String> ids;

private List<Integer> statusList;

// 前端传入的页码
private int pageNo; // 从1开始

// 每页的条数
private int pageSize;

// 数据库的偏移
private int offSet;

// 数据库的大小限制
private int limit;

// 这里重写offSet和limit的get方法
public int getOffSet() {
return (pageNo-1)*pageSize;
}

public int getLimit() {
return pageSize;
}
}

 

linux下删除一个大文件的前n行

 linux, shell  linux下删除一个大文件的前n行已关闭评论
4月 102020
 

删除一个大文件的前n行。

方法一:

例1:删除首行
$ sed -i ‘1d’ a.txt
例2:删除前100行
$ sed -i ‘1,100d’ a.txt
例3:删除尾行
$ sed -i ‘$d’ a.txt

方法二:(举例:删除了前2行)
1.将第三行开始的内容导入新文件
tail -n +3 old_file > new_file
2.将新文件重命名为老文件
mv new_file old_file
这样就删除了前2行,速度要比sed命令快

kill -USR1 参数介绍

 开发  kill -USR1 参数介绍已关闭评论
4月 072020
 

以下为一个典型的nginx日志分割脚本:
#!/bin/bash
savepath_log=’/home/nginx/logs’
nglogs=’/opt/nginx/logs’
mkdir -p $saveptah_logs/$(data +%Y)/$(date +%m)
mv $nglogs/access.log $savepath_log/$(data +%Y)/$(date +%m)/access.$(date +%Y%m%d).log
mv $nglogs/error.log $savepath_log/$(data +%Y)/$(date +%m)/error.$(date +%Y%m%d).log
kill -USR1 `cat /opt/nginx/logs/nginx.pid`

最后一句是什么意思? USR1是什么参数?

通过kill -l可以看到,-USR1 等于 kill -10,是用户定义的进程信号,USR1亦通常被用来告知应用程序重载配置文件;例如,向Apache HTTP服务器发送一个USR1信号将导致以下步骤的发生:停止接受新的连接,等待当前连接停止,重新载入配置文件,重新打开日志文件,重启服务器,从而实现相对平滑的不关机的更改。

从脚本可以看出,当执行脚本时,会把access.log和error.log移到日志目录,所以原来nginx的logs目录下就没有access.log和error.log了,使用kill -USR1 nginx.pid 重新平滑的生成了这两个日志文件,相当于使用了nginx -s reload.

 

 Posted by at 下午2:52

Linux里使用shell中的$(( ))、$( )、“与${ }及区别

 linux, shell  Linux里使用shell中的$(( ))、$( )、“与${ }及区别已关闭评论
4月 072020
 
转一篇linux下关于“$(( ))、$( )、“与${ }”使用及区别的好文章。来自:https://blog.csdn.net/number_0_0/article/details/73291182
命令替换

在bash中,$( )` `(反引号)都是用来作命令替换的。
命令替换与变量替换差不多,都是用来重组命令行的,先完成引号里的命令行,然后将其结果替换出来,再重组成新的命令行。

exp 1

  1. $ echo today is $(date “+%Y-%m-%d”)
  2. today is 2014-07-01
$( )与``

在操作上,这两者都是达到相应的效果,但是建议使用$( ),理由如下:

  • ``很容易与”搞混乱,尤其对初学者来说。
  • 在多层次的复合替换中,``必须要额外的跳脱处理(反斜线),而$( )比较直观。
  • 最后,$( )的弊端是,并不是所有的类unix系统都支持这种方式,但反引号是肯定支持的。

exp 2

  1. # 将cmd1执行结果作为cmd2参数,再将cmd2结果作为cmd3的参数
  2. cmd3 $(cmd2 $(cmd1))
  3. # 如果是用反引号,直接引用是不行的,还需要作跳脱处理
  4. cmd3 `cmd2 \`cmd1\“
${ }变量替换

一般情况下,$var${var}是没有区别的,但是用${ }会比较精确的界定变量名称的范围

  1. $ A=B
  2. $ echo ${A}B
  3. BB

取路径、文件名、后缀
先赋值一个变量为一个路径,如下:
file=/dir1/dir2/dir3/my.file.txt

命令 解释 结果
${file#*/} 拿掉第一条 / 及其左边的字符串 dir1/dir2/dir3/my.file.txt
${file##*/} 拿掉最后一条 / 及其左边的字符串 my.file.txt
${file#*.} 拿掉第一个 . 及其左边的字符串 file.txt
${file##*.} 拿掉最后一个 . 及其左边的字符串 txt
${file%/*} 拿掉最后一条 / 及其右边的字符串 /dir1/dir2/dir3
${file%%/*} 拿掉第一条 / 及其右边的字符串 (空值)
${file%.*} 拿掉最后一个 . 及其右边的字符串 /dir1/dir2/dir3/my.file
${file%%.*} 拿掉第一个 . 及其右边的字符串 /dir1/dir2/dir3/my

记忆方法如下:

  • # 是去掉左边(在键盘上 # 在 $ 之左边)
  • % 是去掉右边(在键盘上 % 在 $ 之右边)
  • 单一符号是最小匹配;两个符号是最大匹配
  • *是用来匹配不要的字符,也就是想要去掉的那部分
  • 还有指定字符分隔号,与*配合,决定取哪部分

取子串及替换

命令 解释 结果
${file:0:5} 提取最左边的 5 个字节 /dir1
${file:5:5} 提取第 5 个字节右边的连续 5 个字节 /dir2
${file/dir/path} 将第一个 dir 提换为 path /path1/dir2/dir3/my.file.txt
${file//dir/path} 将全部 dir 提换为 path /path1/path2/path3/my.file.txt
${#file} 获取变量长度 27

根据状态为变量赋值

命令 解释 备注
${file-my.file.txt} 若 $file 没设定,则使用 my.file.txt 作传回值 空值及非空值不作处理
${file:-my.file.txt} 若 $file 没有设定或为空值,则使用 my.file.txt 作传回值 非空值时不作处理
${file+my.file.txt} 若$file 设为空值或非空值,均使用my.file.txt作传回值 没设定时不作处理
${file:+my.file.txt} 若 $file 为非空值,则使用 my.file.txt 作传回值 没设定及空值不作处理
${file=txt} 若 $file 没设定,则回传 txt ,并将 $file 赋值为 txt 空值及非空值不作处理
${file:=txt} 若 $file 没设定或空值,则回传 txt ,将 $file 赋值为txt 非空值时不作处理
${file?my.file.txt} 若 $file 没设定,则将 my.file.txt 输出至 STDERR 空值及非空值不作处理
${file:?my.file.txt} 若 $file没设定或空值,则将my.file.txt输出至STDERR 非空值时不作处理

tips:
以上的理解在于, 你一定要分清楚 unset 与 null 及 non-null 这三种赋值状态. 一般而言, : 与 null 有关, 若不带 : 的话, null 不受影响, 若带 : 则连 null 也受影响.

数组

  1. A=“a b c def” # 定义字符串
  2. A=(a b c def) # 定义字符数组
命令 解释 结果
${A[@]} 返回数组全部元素 a b c def
${A[*]} 同上 a b c def
${A[0]} 返回数组第一个元素 a
${#A[@]} 返回数组元素总个数 4
${#A[*]} 同上 4
${#A[3]} 返回第四个元素的长度,即def的长度 3
A[3]=xyz 则是将第四个组数重新定义为 xyz
$(( ))与整数运算

bash中整数运算符号

符号 功能
+ – * / 分别为加、减、乘、除
% 余数运算
& | ^ ! 分别为“AND、OR、XOR、NOT”

在 $(( )) 中的变量名称,可于其前面加 $ 符号来替换,也可以不用。

  1. $ a=5;b=7;c=2
  2. $ echo $((a+b*c))
  3. 19
  4. $ echo $(($a+$b*$c))
  5. 19

进制转换
$(( ))可以将其他进制转成十进制数显示出来。用法如下:
echo $((N#xx))
其中,N为进制,xx为该进制下某个数值,命令执行后可以得到该进制数转成十进制后的值。

  1. $ echo $((2#110)) # 二进制转十进制
  2. 6
  3. $ echo $((16#2a)) # 十六进制转十进制
  4. 42
  5. $ echo $((8#11)) # 八进制转十进制
  6. 9

(( ))重定义变量值

  1. $ a=5;b=7
  2. $ ((a++));echo $a
  3. 6
  4. $ ((a–));echo $a
  5. 5
$ ((a<b));echo $? 0

使用(( ))作整数测试时,不要跟[ ]的整数测试搞混乱了。

flutter, “Running multiple emulators with the same AVD is an experimental feature”,’not applicable for the main.dart configuration’,排查

 flutter  flutter, “Running multiple emulators with the same AVD is an experimental feature”,’not applicable for the main.dart configuration’,排查已关闭评论
4月 022020
 

flutter编译运行出现下面问题,可通过下面方法排查

Q: emulator: ERROR: Running multiple emulators with the same AVD is an experimental feature

Removing the .lock files did the trick for me. Find the avd and remove the lock files. In a Mac .android/avd/’NAMEOFAVD.avd directory . The files I removed were hardware-qemu.ini.lock and multiinstance.lock.

Q: I want to run it using the emulator, but it is grayed out. The message “not applicable for the main.dart configuration” appears.

1.GO TO PROJECT STRUCTURE>PROJECT>NOSDK
2.Change NOSDK to the latest ANDROID API PLATFORM
3.THEN GO TO MODULE DO THE SAME

 

PM2启动服务提示:Error: ENOENT: no such file or directory, uv_cwd 解决办法

 Nodejs, pm2  PM2启动服务提示:Error: ENOENT: no such file or directory, uv_cwd 解决办法已关闭评论
3月 232020
 

PM2中重启服务时,出现下面提示:

PM2: path.js:422
PM2: var path = (i >= 0) ? arguments[i] : process.cwd();
PM2: ^
PM2:
PM2: Error: ENOENT: no such file or directory, uv_cwd
PM2: at Error (native)
PM2: at Object.posix.resolve (path.js:422:50)
PM2: at Function.Module._resolveLookupPaths (module.js:248:17)
PM2: at Function.Module._resolveFilename (module.js:326:31)
PM2: at Function.Module._load (module.js:286:25)
PM2: at Module.require (module.js:365:17)
PM2: at require (module.js:384:17)
PM2: at Object.<anonymous> (/usr/local/bin/node_modules/pm2/lib/ProcessContainer.js:12:15)
PM2: at Module._compile (module.js:434:26)
PM2: at Object.Module._extensions..js (module.js:452:10)

 

出现这种情况原因很可能是你不经意间修改了当时启动服务时的目录,比如修改了目录名,移动了目录等, 可以通过下面的方法核实下:

原因:

  1. 通过pm2 list  中找到不能重启的服务的进程号pid
  2. 通过  ls -l /proc/pid(上面1找到的pid)/cwd, 检查下这个目录是不是被删除了?

 

最终解决方案:

  1. ps ax | grep PM2
  2. 找到pm2进程
  3.  kill pid(进程号)
  4.  pm2 list(或是其他的pm2 命令对pm2 进行重启)