shell编程:利用SSH实现分布式应用的一键安装部署②(脚本安装java环境、脚本安装配置zookeeper、scala、kafka)

news2024/12/26 18:24:15

上一节:函数封装

②脚本安装java环境、脚本安装配置zookeeper、scala、kafka

1 脚本一键部署kafka分布式应用

1.1 脚本安装配置java环境

准备好java安装包,存放到/opt/tmp目录下。我这里使用的是jdk-8u212-linux-x64.tar.gz,在网上找对应的版本下载即可。

1.1.1 部署流程思路

步骤一:传输安装包;

步骤二:判断路径存在,若不存在则创建source路径;

步骤三:解压安装包到应用路径;

步骤四:配置环境变量;

步骤五:验证java是否安装成功。

LOCAL_DIR="/opt/tmp"
PACKAGE_DIR="/opt/package"
APP_DIR="/opt/source"
JDK_NAME="jdk-8u212-linux-x64.tar.gz"
# 安装JDK
remote_transfer $LOCAL_DIR/$JDK_NAME $PACKAGE_DIR
remote_execute "if [ ! -d $APP_DIR ];then mkdir -p $APP_DIR;fi"
remote_execute "tar zxvf $PACKAGE_DIR/$JDK_NAME -C $APP_DIR"

cat > $LOCAL_DIR/java.sh << EOF
export JAVA_HOME=/opt/source/jdk1.8.0_212
export PATH=\$PATH:\$JAVA_HOME/bin:\$JAVA_HOME/jre/bin
export JAVA_HOME PATH
EOF

remote_transfer $LOCAL_DIR/java.sh /etc/profile.d/
remote_execute "source /etc/profile.d/java.sh"
remote_execute "java -version"

执行:

sh install.sh
tailf output.log

验证:

ll /opt/tmp
-rw-r--r-- 1 root root       116 Aug  8 03:47 java.sh
-rw-r--r-- 1 root root 195013152 Aug  7 23:37 jdk-8u212-linux-x64.tar.gz
ll /opt/package
-rw-r--r-- 1 root root 195013152 Aug  8 03:47 jdk-8u212-linux-x64.tar.gz
ll /opt/source
drwxr-xr-x 7 10 143 245 Apr  2  2019 jdk1.8.0_212

1.2 脚本安装配置zookeeper

准备好zookeeper安装包,存放到/opt/tmp目录下。我这里使用的是apache-zookeeper-3.7.2-bin.tar.gz,在网上找对应的版本下载即可。

ZK_NAME="apache-zookeeper-3.7.2-bin.tar.gz"
1.2.1 部署流程思路

步骤一:管理主机传输zookeeper安装包到三节点;

remote_transfer $LOCAL_DIR/$ZK_NAME $PACKAGE_DIR

步骤二:解压安装包;

tar -zxvf apache-zookeeper-3.7.2-bin.tar.gz -C /opt/source/

remote_execute "tar zxvf $PACKAGE_DIR/$ZK_NAME -C $APP_DIR"

步骤三:创建zookeeper软连接;

ln -sv /opt/source/apache-zookeeper-3.7.2-bin/ /opt/source/zookeeper

remote_execute "if [ -e $APP_DIR/zookeeper ];then rm -f $APP_DIR/zookeeper"
remote_execute "ln -sv $APP_DIR/apache-zookeeper-3.7.2-bin $APP_DIR/zookeeper"

步骤四:修改zookeeper配置文件;

(1)、样例配置文件更名

cp zoo_sample.cfg zoo.cfg

remote_execute "cp $APP_DIR/zookeeper/conf/zoo_sample.cfg $APP_DIR/zookeeper/conf/zoo.cfg"

(2)、配置文件zoo.cfg末尾增加内容

server.1=10.0.1.10:2888:3888

server.2=10.0.1.20:2888:3888

server.3=10.0.1.30:2888:3888

cat > $LOCAL_DIR/zoo_tmp.conf << EOF
server.1=10.0.1.10:2888:3888
server.2=10.0.1.20:2888:3888
server.3=10.0.1.30:2888:3888
EOF

remote_transfer $LOCAL_DIR/zoo_tmp.conf /tmp
remote_execute "cat /tmp/zoo_tmp.conf >> $APP_DIR/zookeeper/conf/zoo.cfg"

(3)、创建zookeeper数据目录

mkdir /data/zk -pv

remote_execute "if [ -e /data/zk ];then rm -rf /data/zk;fi"
remote_execute "mkdir /data/zk -pv"

(4)、配置文件数据目录更改

dataDir=/tmp/zookeeper更改为dataDir=/data/zk

remote_execute "sed -i 's/dataDir=\/tmp\/zookeeper/dataDir=\/data\/zk/g' $APP_DIR/zookeeper/conf/zoo.cfg"

(5)、数据目录生成唯一的myid文件

node01:echo 1> /data/zk/myid

node02:echo 2 > /data/zk/myid

node03:echo 3 > /data/zk/myid

remote_execute 'if [ `hostname` == "node01" ];then echo 1 > /data/zk/myid;fi'
remote_execute 'if [ `hostname` == "node02" ];then echo 2 > /data/zk/myid;fi'
remote_execute 'if [ `hostname` == "node03" ];then echo 3 > /data/zk/myid;fi'

步骤五:判断主机是否有zookeeper进程,如有则kill

remote_execute "jps | grep QuorumPeerMain | grep -v grep | awk '{print \$1}' > /tmp/zk.pid"
remote_execute 'if [ -s /tmp/zk.pid ];then kill -9 `cat /tmp/zk.pid`;fi'

步骤六:启动服务并验证。

/opt/source/zookeeper/bin/zkServer.sh start

/opt/source/zookeeper/bin/zkServer.sh status

remote_execute "$APP_DIR/zookeeper/bin/zkServer.sh start"
remote_execute "$APP_DIR/zookeeper/bin/zkServer.sh status"

完整代码:

ZK_NAME="apache-zookeeper-3.7.2-bin.tar.gz"
# 安装配置zookeeper,并启动服务
function install_zk
{
remote_transfer $LOCAL_DIR/$ZK_NAME $PACKAGE_DIR
remote_execute "tar zxf $PACKAGE_DIR/$ZK_NAME -C $APP_DIR"

remote_execute "if [ -e $APP_DIR/zookeeper ];then rm -f $APP_DIR/zookeeper;fi"
remote_execute "ln -sv $APP_DIR/apache-zookeeper-3.7.2-bin $APP_DIR/zookeeper"

remote_execute "cp $APP_DIR/zookeeper/conf/zoo_sample.cfg $APP_DIR/zookeeper/conf/zoo.cfg"

cat > $LOCAL_DIR/zoo_tmp.conf << EOF
server.1=10.0.1.10:2888:3888
server.2=10.0.1.20:2888:3888
server.3=10.0.1.30:2888:3888
EOF

remote_transfer $LOCAL_DIR/zoo_tmp.conf /tmp
remote_execute "cat /tmp/zoo_tmp.conf >> $APP_DIR/zookeeper/conf/zoo.cfg"

remote_execute "if [ -e /data/zk ];then rm -rf /data/zk;fi"
remote_execute "mkdir /data/zk -pv"

remote_execute "sed -i 's/dataDir=\/tmp\/zookeeper/dataDir=\/data\/zk/g' $APP_DIR/zookeeper/conf/zoo.cfg"

remote_execute 'if [ `hostname` == "node01" ];then echo 1 > /data/zk/myid;fi'
remote_execute 'if [ `hostname` == "node02" ];then echo 2 > /data/zk/myid;fi'
remote_execute 'if [ `hostname` == "node03" ];then echo 3 > /data/zk/myid;fi'

remote_execute "jps | grep QuorumPeerMain | grep -v grep | awk '{print \$1}' > /tmp/zk.pid"
remote_execute 'if [ -s /tmp/zk.pid ];then kill -9 `cat /tmp/zk.pid`;fi'

remote_execute "$APP_DIR/zookeeper/bin/zkServer.sh start"
remote_execute "$APP_DIR/zookeeper/bin/zkServer.sh status"
}
install_zk

验证:

[root@node01 shell]# tailf output.log
64 ++++command < /opt/source/zookeeper/bin/zkServer.sh start > in host: node01
ZooKeeper JMX enabled by default
Using config: /opt/source/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
successful.command < /opt/source/zookeeper/bin/zkServer.sh start >
65 ++++command < /opt/source/zookeeper/bin/zkServer.sh start > in host: node02
ZooKeeper JMX enabled by default
Using config: /opt/source/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
successful.command < /opt/source/zookeeper/bin/zkServer.sh start >
66 ++++command < /opt/source/zookeeper/bin/zkServer.sh start > in host: node03
ZooKeeper JMX enabled by default
Using config: /opt/source/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
successful.command < /opt/source/zookeeper/bin/zkServer.sh start >

1.3 脚本安装配置scala

准备好scala安装包,存放到/opt/tmp目录下。我这里使用的是scala-2.12.11.tgz,在网上找对应的版本下载即可。

1.3.1 部署流程思路

第一步:管理主机(/opt/tmp)传输scala安装包到远端生产主机目录(/opt/package);

第二步:远端生产主机解压缩scala安装包到安装目录(/opt/source);

第三步:管理主机(/opt/tmp)本地生成scala环境变量配置文件scala.sh;

第四步:管理主机传输scala.sh到所有远端生产主机/etc/profile.d/下;

第五步:所有远端生产主机使用source指令生效scala环境变量;

第六步:使用scala-version验证scala环境是否配置成功。

SCALA_NAME="scala-2.12.11.tgz"
function install_scala
{
remote_transfer $LOCAL_DIR/$SCALA_NAME $PACKAGE_DIR
remote_execute "tar zxf $PACKAGE_DIR/$SCALA_NAME -C $APP_DIR"

cat > $LOCAL_DIR/scala.sh << EOF
export SCALA_HOME=$APP_DIR/scala-2.12.11
export PATH=\$PATH:\$SCALA_HOME/bin
export SCALA_HOME PATH
EOF

remote_transfer $LOCAL_DIR/scala.sh /etc/profile.d/
remote_execute "source /etc/profile.d/scala.sh"
remote_execute "scala -version"
}
install_scala

验证:

[root@node01 shell]# tailf output.log
82 ++++command < scala -version > in host: node01
Scala code runner version 2.12.11 -- Copyright 2002-2020, LAMP/EPFL and Lightbend, Inc.
successful.command < scala -version >
83 ++++command < scala -version > in host: node02
Scala code runner version 2.12.11 -- Copyright 2002-2020, LAMP/EPFL and Lightbend, Inc.
successful.command < scala -version >
84 ++++command < scala -version > in host: node03
Scala code runner version 2.12.11 -- Copyright 2002-2020, LAMP/EPFL and Lightbend, Inc.
successful.command < scala -version >

1.4 脚本安装配置kafka

1.4.1 部署流程思路

第一步:管理主机(/opt/tmp)传输kafka安装包到所有远端生产主机/opt/package

第二步:所有远端生产主机(/opt/package)解压缩kafka安装包到安装目录(/opt/source)

remote_transfer $LOCAL_DIR/$KAFKA_NAME $PACKAGE_DIR
remote_execute "tar zxf $PACKAGE_DIR/$KAFKA_NAME -C $APP_DIR"

第三步:创建kafka_2.12-2.6.1目录软连接,创建之前先判断软连接是否存在,如果存在则删除

remote_execute "if [ -e $APP_DIR/kafka ];then rm -f $APP_DIR/kafka;fi"
remote_execute "ln -sv $APP_DIR/kafka_2.12-2.6.1 $APP_DIR/kafka"

第四步:创建kafka数据存储目录;创建之前先判断该目录是否存在,如果存在则删除

remote_execute "if [ -e /data/kafka/log ];then rm -f /data/kafka/log"
remote_execute "mkdir -p /data/kafka/log"

第五步:修改kafka配置文件(/opt/source/kafka/config/server.properties)

(1)、修改内容

zookeeper.connect=localhost:2181替换为

zookeeper.connect=10.0.1.10:2181,10.0.1.20:2181,10.0.1.30:2181

remote_execute "sed -i '/zookeeper.connect=localhost:2181/d' $APP_DIR/kafka/config/server.properties"
remote_execute "sed -i '\$azookeeper.connect=10.0.1.10:2181,10.0.1.20:2181,10.0.1.30:2181' $APP_DIR/kafka/config/server.properties"

(2)、修改内容

broker.id=0修改为:

node01:broker.id=100

node02:broker.id=101

node03:broker.id=102

remote_execute "if [ \`hostname\` == "node01" ];then sed -i 's/broker.id=0/broker.id=100/g' $APP_DIR/kafka/config/server.properties;fi"
remote_execute "if [ \`hostname\` == "node02" ];then sed -i 's/broker.id=0/broker.id=101/g' $APP_DIR/kafka/config/server.properties;fi"
remote_execute "if [ \`hostname\` == "node03" ];then sed -i 's/broker.id=0/broker.id=102/g' $APP_DIR/kafka/config/server.properties;fi"

(3)、追加内容

node01:listeners=PLAINTEXT://10.0.1.10:9092

node02:listeners=PLAINTEXT://10.0.1.20:9092

node03:listeners=PLAINTEXT://10.0.1.30:9092

remote_execute "if [ \`hostname\` == "node01" ];then sed -i '\$alisteners=PLAINTEXT://10.0.1.10:9092' $APP_DIR/kafka/config/server.properties;fi"
remote_execute "if [ \`hostname\` == "node02" ];then sed -i '\$alisteners=PLAINTEXT://10.0.1.20:9092' $APP_DIR/kafka/config/server.properties;fi"
remote_execute "if [ \`hostname\` == "node03" ];then sed -i '\$alisteners=PLAINTEXT://10.0.1.30:9092' $APP_DIR/kafka/config/server.properties;fi"

(4)、修改内容

log.dirs=/tmp/kafka-logs修改为log.dirs=/data/kafka/log

remote_execute "sed -i 's/log.dirs=\/tmp\/kafka-logs/log.dirs=\/data\/kafka\/log/g' $APP_DIR/kafka/config/server.properties"

第六步:启动kafka服务;启动前先判断kafka进程是否存在,如果存在先杀死

remote_execute "jps |grep Kafka | grep -v grep | awk '{print \$1}' > /tmp/kafka.pid"
remote_execute "if [ -s /tmp/kafka.pid ];then kill -9 \`cat /tmp/kafka.pid\`;fi"

验证:

[root@node01 shell]# tailf output.log
136 ++++command < /opt/source/kafka/bin/kafka-server-start.sh -daemon /opt/source/kafka/config/server.properties > in host: node01
successful.command < /opt/source/kafka/bin/kafka-server-start.sh -daemon /opt/source/kafka/config/server.properties >
137 ++++command < /opt/source/kafka/bin/kafka-server-start.sh -daemon /opt/source/kafka/config/server.properties > in host: node02
successful.command < /opt/source/kafka/bin/kafka-server-start.sh -daemon /opt/source/kafka/config/server.properties >
138 ++++command < /opt/source/kafka/bin/kafka-server-start.sh -daemon /opt/source/kafka/config/server.properties > in host: node03
successful.command < /opt/source/kafka/bin/kafka-server-start.sh -daemon /opt/source/kafka/config/server.properties >
[root@node01 shell]# jps
31425 QuorumPeerMain
35350 Jps
32476 Kafka

第七步:创建测试topic(test),并查看详情以验证kafka环境是否配置成功。

remote_execute "$APP_DIR/kafka/bin/kafka-server-start.sh -daemon $APP_DIR/kafka/config/server.properties"
sleep 30
remote_execute "if [ \`hostname\` == "node01" ];then $APP_DIR/kafka/bin/kafka-topics.sh --zookeeper localhost --create --topic test --partitions 5 --replication-factor=2;fi"
sleep 5
remote_execute "if [ \`hostname\` == "node01" ];then $APP_DIR/kafka/bin/kafka-topics.sh --zookeeper localhost --topic test --describe;fi"

整个项目完整代码:

[root@node01 shell]# cat /shell/init-kafka.sh
#!/bin/bash
#
if [ -e ./output.log ];then
    rm -rf ./output.log
fi
exec 1>> ./output.log 2>&1
set -e
# 初始化变量
HOST_LIST="node01 node02 node03"
USER_PASS="000000"
CMD_NUM=0
LOCAL_DIR="/opt/tmp"
PACKAGE_DIR="/opt/package"
APP_DIR="/opt/source"
JDK_NAME="jdk-8u212-linux-x64.tar.gz"
ZK_NAME="apache-zookeeper-3.7.2-bin.tar.gz"
SCALA_NAME="scala-2.12.11.tgz"
KAFKA_NAME="kafka_2.12-2.6.1.tgz"

# 多主机执行主机指令封装
function remote_execute
{
   for host in $HOST_LIST;do
       CMD_NUM=`expr $CMD_NUM + 1`
       echo "$CMD_NUM ++++command < $@ > in host: $host"
       sshpass -p$USER_PASS ssh -o StrictHostKeyChecking=no root@$host $@
       if [ $? -eq 0 ];then
             echo "successful.command < $@ > "
       else
             echo "sorry.command < $@ > "
       fi
    done
}
# 示例:remote_execute 'du'

# 多主机传输文件函数封装
function remote_transfer
{
    SRC_FILE=$1
    DST_DIR=$2
    # 函数必须有2个参数,第一个参数是本地文件或目录,第二个参数为远端主机目录
    if [ $# -lt 2 ];then
         echo "Usage:$0 <file|dir <dst_dir>>"
         exit 1
    fi
    # 判断第一个参数是否存在,如果不存在则直接退出并提示给用户
    if [ ! -e $SRC_FILE ];then
         echo "ERROR - $SEC_FIEL is not exist,Please check...."
         exit 1
    fi
    for host in $HOST_LIST;do
    echo "+++++++++++Transfer FILE TO HOST: $host+++++++++++"
    CMD_NUM=`expr $CMD_NUM + 1`
    # 判断目录参数是否存在,如果不存在则直接创建
        ssh -o StrictHostKeyChecking=no root@$host "if [ ! -e $DST_DIR ];then mkdir $DST_DIR -p;fi"

        scp -r -o StrictHostKeyChecking=no $SRC_FILE root@$host:$DST_DIR/
        if [ $? -eq 0 ];then
            echo "Remote Host:$host - $CMD_NUM - INFO -SCP $SRC_FILE TO dir $DST_DIR success"
        else
            echo "Remote Host:$host - $CMD_NUM - ERROR -SCP $SRC_FILE TO dir $DST_DIR filed"
        fi
    done
}

# 示例:remote_transfer output.log /tmp/log
# 关闭firewalld和selinux
function stop_firewalld
{
remote_execute "systemctl stop firewalld"
remote_execute "systemctl disable firewalld"
remote_execute "setenforce 0"
remote_execute "sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux"
}
stop_firewalld
# 安装JDK
function install_java
{
remote_transfer $LOCAL_DIR/$JDK_NAME $PACKAGE_DIR
remote_execute "if [ ! -d $APP_DIR ];then mkdir -p $APP_DIR;fi"
remote_execute "tar zxf $PACKAGE_DIR/$JDK_NAME -C $APP_DIR"

cat > $LOCAL_DIR/java.sh << EOF
export JAVA_HOME=/opt/source/jdk1.8.0_212
export PATH=\$PATH:\$JAVA_HOME/bin:\$JAVA_HOME/jre/bin
export JAVA_HOME PATH
EOF

remote_transfer $LOCAL_DIR/java.sh /etc/profile.d/
remote_execute "source /etc/profile.d/java.sh"
remote_execute "java -version"
}
install_java
# 安装配置zookeeper,并启动服务
function install_zk
{
remote_transfer $LOCAL_DIR/$ZK_NAME $PACKAGE_DIR
remote_execute "tar zxf $PACKAGE_DIR/$ZK_NAME -C $APP_DIR"

remote_execute "if [ -e $APP_DIR/zookeeper ];then rm -f $APP_DIR/zookeeper;fi"
remote_execute "ln -sv $APP_DIR/apache-zookeeper-3.7.2-bin $APP_DIR/zookeeper"

remote_execute "cp $APP_DIR/zookeeper/conf/zoo_sample.cfg $APP_DIR/zookeeper/conf/zoo.cfg"

cat > $LOCAL_DIR/zoo_tmp.conf << EOF
server.1=10.0.1.10:2888:3888
server.2=10.0.1.20:2888:3888
server.3=10.0.1.30:2888:3888
EOF

remote_transfer $LOCAL_DIR/zoo_tmp.conf /tmp
remote_execute "cat /tmp/zoo_tmp.conf >> $APP_DIR/zookeeper/conf/zoo.cfg"

remote_execute "if [ -e /data/zk ];then rm -rf /data/zk;fi"
remote_execute "mkdir /data/zk -pv"

remote_execute "sed -i 's/dataDir=\/tmp\/zookeeper/dataDir=\/data\/zk/g' $APP_DIR/zookeeper/conf/zoo.cfg"

remote_execute 'if [ `hostname` == "node01" ];then echo 1 > /data/zk/myid;fi'
remote_execute 'if [ `hostname` == "node02" ];then echo 2 > /data/zk/myid;fi'
remote_execute 'if [ `hostname` == "node03" ];then echo 3 > /data/zk/myid;fi'

remote_execute "jps | grep QuorumPeerMain | grep -v grep | awk '{print \$1}' > /tmp/zk.pid"
remote_execute 'if [ -s /tmp/zk.pid ];then kill -9 `cat /tmp/zk.pid`;fi'

remote_execute "$APP_DIR/zookeeper/bin/zkServer.sh start"
remote_execute "$APP_DIR/zookeeper/bin/zkServer.sh status"
}
install_zk

# 安装配置scala环境
function install_scala
{
remote_transfer $LOCAL_DIR/$SCALA_NAME $PACKAGE_DIR
remote_execute "tar zxf $PACKAGE_DIR/$SCALA_NAME -C $APP_DIR"

cat > $LOCAL_DIR/scala.sh << EOF
export SCALA_HOME=$APP_DIR/scala-2.12.11
export PATH=\$PATH:\$SCALA_HOME/bin
export SCALA_HOME PATH
EOF

remote_transfer $LOCAL_DIR/scala.sh /etc/profile.d/
remote_execute "source /etc/profile.d/scala.sh"
remote_execute "scala -version"
}
install_scala

# 安装配置kafka,并启动服务
function install_kafka
{
remote_transfer $LOCAL_DIR/$KAFKA_NAME $PACKAGE_DIR
remote_execute "tar zxf $PACKAGE_DIR/$KAFKA_NAME -C $APP_DIR"

remote_execute "if [ -e $APP_DIR/kafka ];then rm -rf $APP_DIR/kafka;fi"
remote_execute "ln -sv $APP_DIR/kafka_2.12-2.6.1 $APP_DIR/kafka"

remote_execute "if [ -e /data/kafka/log ];then rm -rf /data/kafka/log;fi"
remote_execute "mkdir -p /data/kafka/log"

remote_execute "sed -i '/zookeeper.connect=localhost:2181/d' $APP_DIR/kafka/config/server.properties"
remote_execute "sed -i '\$azookeeper.connect=10.0.1.10:2181,10.0.1.20:2181,10.0.1.30:2181' $APP_DIR/kafka/config/server.properties"

remote_execute "if [ \`hostname\` == "node01" ];then sed -i 's/broker.id=0/broker.id=100/g' $APP_DIR/kafka/config/server.properties;fi"
remote_execute "if [ \`hostname\` == "node02" ];then sed -i 's/broker.id=0/broker.id=101/g' $APP_DIR/kafka/config/server.properties;fi"
remote_execute "if [ \`hostname\` == "node03" ];then sed -i 's/broker.id=0/broker.id=102/g' $APP_DIR/kafka/config/server.properties;fi"

remote_execute "if [ \`hostname\` == "node01" ];then sed -i '\$alisteners=PLAINTEXT://10.0.1.10:9092' $APP_DIR/kafka/config/server.properties;fi"
remote_execute "if [ \`hostname\` == "node02" ];then sed -i '\$alisteners=PLAINTEXT://10.0.1.20:9092' $APP_DIR/kafka/config/server.properties;fi"
remote_execute "if [ \`hostname\` == "node03" ];then sed -i '\$alisteners=PLAINTEXT://10.0.1.30:9092' $APP_DIR/kafka/config/server.properties;fi"

remote_execute "sed -i 's/log.dirs=\/tmp\/kafka-logs/log.dirs=\/data\/kafka\/log/g' $APP_DIR/kafka/config/server.properties"

remote_execute "jps |grep Kafka | grep -v grep | awk '{print \$1}' > /tmp/kafka.pid"
remote_execute "if [ -s /tmp/kafka.pid ];then kill -9 \`cat /tmp/kafka.pid\`;fi"

remote_execute "$APP_DIR/kafka/bin/kafka-server-start.sh -daemon $APP_DIR/kafka/config/server.properties"

sleep 30

remote_execute "if [ \`hostname\` == "node01" ];then $APP_DIR/kafka/bin/kafka-topics.sh --zookeeper localhost --create --topic test --partitions 5 --replication-factor=2;fi"

sleep 5

remote_execute "if [ \`hostname\` == "node01" ];then $APP_DIR/kafka/bin/kafka-topics.sh --zookeeper localhost --topic test --describe;fi"
}
install_kafka

编写脚本的时候需要注意:

set -e 是一个命令,用来设置脚本在遇到错误时立即退出。

单引号和双引号的区别:

在Shell脚本中,双引号 " " 和单引号 ' ' 都用于定义字符串,但它们之间有以下主要区别:

转义字符

    • 在双引号中,大多数特殊字符会被识别并解释,例如 $\!(在某些Shell中)等。如果需要在字符串中包含这些特殊字符的字面值,可以使用反斜杠 \ 来转义它们。
    • 在单引号中,所有特殊字符都会被当作普通字符处理,不会被解释或转义。这意味着即使使用 \ 也无法转义特殊字符。

变量替换

    • 在双引号中,变量会被替换为它们的值。例如,如果有一个变量 var="world",那么在字符串 "Hello $var" 中,$var 会被替换为 "world"
    • 在单引号中,变量不会被替换,即使变量名前面有 $ 符号。例如,'Hello $var' 会原样输出为 Hello $var

空格和换行

    • 双引号内的空格和换行会被保留为字符串的一部分。
    • 单引号内的空格和换行也会被保留,但它们不会被解释为特殊字符。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

excel向下合并空值

方方格子&#xff1a;合并转换——合并空值 选择向右或者向下

基于ssm+vue+uniapp的英语学习交流平台小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…

【网络】套接字(socket)编程——UDP版

1.socket 1.1.什么是socket Socket 的中文翻译过来就是“套接字”。 套接字是什么&#xff0c;我们先来看看它的英文含义&#xff1a;插座。 Socket 就像一个电话插座&#xff0c;负责连通两端的电话&#xff0c;进行点对点通信&#xff0c;让电话可以进行通信&#xff0c;端…

鸿蒙(API 12 Beta3版)【音视频解封装】 文件解析封装

开发者可以调用本模块的Native API接口&#xff0c;完成音视频解封装&#xff0c;即从比特流数据中取出音频、视频等媒体帧数据。 当前支持的数据输入类型有&#xff1a;远程连接(http协议、HLS协议)和文件描述符(fd)。 支持的解封装格式如下&#xff1a; 媒体格式封装格式码…

高效修复,2024年SD卡损坏数据恢复利器推荐

如果你也是爱记录生活的小伙伴外出游玩的时候肯定会带上带你的长枪短炮吧。如果预算充足可以直接考虑双盘位的设备&#xff0c;为你的图片上个保险。如果是单卡槽的设备回来的时候发现照片全无了咋办&#xff0c;这次我们就探讨下sd卡数据恢复要怎么进行吧。 1.福昕恢复数据 …

【递归】3.反转链表

leetcode题目连接&#xff1a;https://leetcode.cn/problems/reverse-linked-list/题解过程&#xff1a; 1.找到重复的子问题 要逆序第一个节点&#xff0c;就把后面的节点都逆序一遍 2.关注到具体的子问题的实现 第一步&#xff1a;将当前节点的后面所有节点逆置 第二步&…

【自动驾驶】ROS中自定义格式的服务通信,含命令行动态传参(c++)

目录 通信流程创建服务器端及客户端新建服务通讯文件修改service的xml及cmakelistCMakeLists.txt编辑 msg 相关配置编译消息相关头文件在cmakelist中包含头文件的路径在service包下编写service.cpp在client包下编写client.cpp测试运行查询服务的相关指令列出目前的所有服务&…

毛骨悚然,ChatGPT诡异尖叫、模仿用户说话,GPT-4o被曝行为失控

ChatGPT被曝存在失控行为&#xff0c;原本是用户和ChatGPT正常的语音对话&#xff0c;但ChatGPT却突然大喊了一声“no”&#xff0c;随即竟模仿起了用户的声音&#xff01; 下面就是这段让人毛骨悚然的声音片段&#xff1a; ChatGPT失控行为首次公开很多网友表示&#xff0c;第…

【MySQL】2.MySQL实际操作

目录 一、数据分析基本流程 注&#xff1a;Navicat快捷键 二、获取数据后的代码操作 &#xff08;1&#xff09;探索数据&#xff0c;查看定义 &#xff08;2&#xff09;筛选有用的字段 &#xff08;3&#xff09;建新表&#xff08;查询建表插值 三合一&#xff09; 注意…

揭秘Java 8新宠儿:初识Optional,让你的代码告别空指针烦恼

文章目录 前言一、Optional基础二、使用步骤1.创建Optional实例1.常用方法 前言 Java 8 引入了一个非常有用的类 Optional&#xff0c;它旨在减少空指针异常&#xff08;NullPointerException&#xff09;的发生。Optional 类是一个可以包含也可以不包含非null值的容器对象。如…

20240813在荣品RK3588S-AHD开发板的预置Android13中挂载ext4格式的256GB的TF卡

df -h mount fdisk无效 20240813在荣品RK3588S-AHD开发板的预置Android13中挂载ext4格式的256GB的TF卡 2024/8/13 11:24 缘起&#xff1a;当时比较便宜96.9&#xffe5;/想看看256GB的TF卡的高速卡的效果&#xff0c;就在京东入手了3张三星的高速TF卡。最近在弄RK3588S&#xf…

4款AI自动生成PPT神器,制作PPT太容易了

在当今数字化时代&#xff0c;无论是职场人士还是在校学生&#xff0c;PPT已经成为工作和学习中不可或缺的展示工具。从项目回顾到学术答辩&#xff0c;甚至是婚礼致辞&#xff0c;一份精心制作的PPT总能给人留下深刻印象。 为了帮助您更高效地完成PPT制作&#xff0c;我们将介…

数据科学、数据分析、人工智能必备知识汇总-----常用数据分析方法-----持续更新

数据科学、数据分析、人工智能必备知识汇总-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/140174015 文章目录 一、对比分析法1. 按时间和地区2. 同比和环比 二、分组分析法三、结构分析法四、交叉分析法五、矩阵分…

【话题】AI时代的程序员:挑战、机遇与核心竞争力的重塑

目录 人工智能时代&#xff0c;程序员如何保持核心竞争力&#xff1f; ​编辑引言 方向一&#xff1a;AI辅助编程对程序员工作的影响 案例 潜在的风险与对策 方向二&#xff1a;程序员应重点发展的核心能力 核心竞争力 如何培养这些能力 方向三&#xff1a;人机协作模式下的职业…

图论------贝尔曼-福德(Bellman-Ford)算法

算法概述&#xff1a; Bellman-Ford算法核心代码如下 for(int i 1;i<n-1;i) for(int j 1;j<m;j) if(dic[v[j]]> dic[u[j]] w[j]] dic[v[j]] dic[u[j]] w[j]; 首先我们要了解一个点就是我们这次不再使用邻接矩阵来存储图的信息&#xff0c;而是定义三个一维数组来…

Kubernetes之pod的污点和容忍度

污点和容忍度 污点&#xff08;Taint&#xff09;&#xff0c;它使节点能够排斥一类特定的 Pod。 容忍度&#xff08;Toleration&#xff09; 是应用于 Pod 上的&#xff0c;容忍度允许调度器调度带有对应污点的 Pod。 容忍度允许调度但并不保证调度&#xff1a;作为其功能的…

构建即时通讯应用:Spring boot高效集成WebSocket、Stomp协议完成前后端持续通信

1. 引入依赖 在你的Spring Boot项目的pom.xml中添加以下依赖&#xff1a; <dependencies><!-- Spring Boot Starter Thymeleaf --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf&…

黑龙江日报报道第5届中国计算机应用技术大赛,赛氪提供赛事支持

2024年7月17日&#xff0c;黑龙江日报、极光新闻对在哈尔滨市举办的第5届中国计算机应用技术大赛全国总决赛进行了深入报道。此次大赛由中国计算机学会主办&#xff0c;中国计算机学会计算机应用专业委员会与赛氪网共同承办&#xff0c;吸引了来自全国各地的顶尖技术团队和选手…

振德医疗选择泛微千里聆RPA,助力电商、人事业务流程自动化

振德医疗用品股份有限公司成立于1994年&#xff0c;中国A股上市公司&#xff0c;是医用敷料和感控防护产品主要的供应商之一。 &#xff08;图片素材来自振德医疗官网&#xff09; 振德医疗的业务在线上线下齐发力。目前拥有5个国内生产基地&#xff0c;3个海外工厂&#xff0…

算法分析报告:商江小智文本生成算法

1. 算法全周期分析 算法安全与监测 信息内容安全&#xff1a;算法通过预处理和特征提取确保输入数据的安全&#xff0c;避免敏感信息泄露。信息源安全&#xff1a;算法依赖于训练数据集&#xff0c;需确保数据来源的合法性和隐私保护。信息安全监测&#xff1a;算法应实时监控…