Linux服务器Shell批量巡检

2023-11-05

关键词:Linux shell 批量巡检

1、批量巡检流程

通过Linux shell脚本实现批量服务器巡检方案,通常脚本由三部分组成,包括:

巡检脚本(实现对性能信息或指标的采集与回传)、巡检脚本下发脚本(由主服务器通过Except工具分别根据待巡检服务器信息列表中的账号密码连接对应主机,将脚本下发至对应主机,再目标主机上执行巡检脚本)、待巡检服务器信息列表(包括待巡检服务器的管理IP和登陆密码)。

由于需要获取服务器软硬件和性能信息,则需要获得各服务器的root权限
由于巡检信息需要回传至主服务器,则需要支持SCP命令
由于实现需要主机间交互,则需要各主机之间支持Expect工具

2、环境参数准备

2.1相关服务器信息

(1)日志上传目标服务器IP地址:作为参数输入或在脚本中预先设置,例如192.168.52.3;
(2)日志上传目标服务器root密码:作为参数输入或在脚本中预先设置,例如123456;
(3)待巡检服务器信息列表:文件格式,作为参数输入或在脚本中预先设置,每一行为一台服务器的IP地址和密码,例如:

(4)服务器支持Expect工具;

2.2日志存储路径

日志上传存储路径:

/tmp/ checklog_directory

本地日志存储路径:

/tmp/ local_serverlog_directory

巡检脚本文件存储路径:

/tmp/check_script

3、Expect工具

Expect是建立在tcl基础上的一个工具,Expect是用来进行自动化控制和测试的工具。主要解决shell脚本中不可交互的问题。通常用于需要手动输入数据的场景,可在脚本中使用expect来实现自动化。

通常远程登录Linux服务器时,运行命令、脚本或程序时,这些命令、脚本或程序都需要在服务器回显某些提示符后,再次从终端输入某些继续运行的指令,由于回显提示符要求不固定,则这些输入都需要人为的手工进行。例如正常远程登录Linux服务器和首次远程登录时服务器的响应步骤并不相同。此时则需要使用expect工具根据程序的提示,模拟标准输入提供给程序,从而实现自动化交互执行。

3.1、命令

Expect工具工作原理即为根据回显内容进行判断,进而执行下一步指令。其主要命令包括:

命令 说明
spawn 启动新的交互进程, 后面跟命令或者指定程序
expect 从进程中接收信息, 如果匹配成功, 就执行expect后的动作
send 向进程发送字符串
send exp_send 用于发送指定的字符串信息
exp_continue 在expect中多次匹配就需要用到
send_user 用来打印输出 相当于shell中的echo
interact 允许用户交互
exit 退出expect脚本
eof expect执行结束, 退出
set 定义变量
puts 输出变量
set timeout 设置超时时间

3.2、安装

(1)安装tcl:

yum install -y tcl tclx tcl-devel


(2)安装expect:

yum –y install expec

3.3、测试

(1)测试脚本

(2)测试结果

4、巡检脚本实现

4.1、脚本实现

文件名为:check_command.sh

#!/bin/bash
#

#检查是否为root权限,否则退出
[ $(id -u) -gt 0 ] && echo "please used the root or sudo " && exit 1

#设置参数
main_ipaddr=$1 #日志上传服务器IP
main_passwd=$2 #日志上传服务器密码
main_log_path="/tmp/checklog_directory" #日志上传路径
local_log_path="/tmp/local_serverlog_directory" #本地日志存储路径
LogName=`ifconfig | grep "inet"|sed '2,4d' |awk -F" " '{print $2}' ``echo "-"``date +%y%m%d%H%M%S` #构造日志名称

#获取系统信息
function get_status(){
echo -e "#系统基础信息:"
OS=` head -n 1 /etc/centos-release ` #系统版本
Kernel=` uname -r ` #系统内核
Hostname=` hostname ` #主机名称
Default_lang=` echo $LANG ` #默认语言
Time=$(date +'%Y-%m-%d %H:%M:%S') #当前时间
Logintime=$(who -b |awk '{print $3,$4}') #此用户登录时间
Uptime=$(uptime|awk '{print $3}'|awk -F "," '{print $1}') #系统已运行时间
Ipaddr=$(ifconfig |grep 'inet ' |awk {'print$2'}|grep -v '127.0.0.1') #IP地址
Netmask=$(ifconfig|grep "inet"|sed '2,4d'|awk -F " " '{print $4}') #掩码
cpu_info=$(cat /proc/cpuinfo|grep "name"|cut  -d: -f2|awk '{print "*"$1,$2,$3,$4}'|uniq -c|sed 's/^[ \t]*//g') #CPU信息
cpu_type=$(grep 'model name' /proc/cpuinfo | uniq | awk -F":" '{print $2}') #CPU型号
cpu_arch=$(uname -m) #CPU架构
cpu_number_physical=$(grep 'physical id' /proc/cpuinfo | sort | uniq | wc -l) #物理CPU数
cpu_number_vir=$(grep 'processor' /proc/cpuinfo | wc -l) #逻辑CPU数
cpu_cores=$(grep 'cores' /proc/cpuinfo | uniq | awk -F":" '{print $NF}' ) #每CPU核心数
Sigle_memory_capacity=$(dmidecode|grep -P -A5 "Memory\s+Device"|grep "Size"|grep -v "Range"|grep '[0-9]'|awk -F ":" '{print $2}'|sed 's/^[ \t]*//g') #单内存容量
Maximum_memory_capacity=$(dmidecode -t 16|grep "Maximum Capacity"|awk -F ":" '{print $2}'|sed 's/^[ \t]*//g') #最大存储容量
Number_of_memory_slots=$(dmidecode -t 16|grep "Number Of Devices"|awk -F ":" '{print $2}'|sed 's/^[ \t]*//g') #内存卡槽数
Memory_total=$(cat /proc/meminfo|grep "MemTotal"|awk '{printf("MemTotal:%1.0fGB\n",$2/1024/1024)}'|awk -F ":" '{print $2}') #理论总内存
Product_name=$(dmidecode|grep -A10 "System Information"|grep "Product Name"|awk -F ":" '{print $2}'|sed 's/^[ \t]*//g') #内存品牌
Process_numbers=$(top -d 2 -n 1 -b|grep "Tasks" |awk -F':' '{print $2}'|awk -F" " '{print $1}') #总进程数
Process_running=$(top -d 2 -n 1 -b|grep "Tasks"|awk -F "[: ,]" '{print $8}') #活跃进程数
Process_sleeping=$(top -d 2 -n 1 -b|grep "Tasks"|awk -F "[: ,]" '{print $11}') #睡眠进程数
Process_stoping=$(top -d 2 -n 1 -b|grep "Tasks"|awk -F "[: ,]" '{print $16}') #停止进程数
Process_zombie=$(top -d 2 -n 1 -b|grep "Tasks"|awk -F "[: ,]" '{print $21}') #僵尸进程数
cpu_load=$(uptime | awk '{for(i=6;i<=NF;i++) printf $i""FS;print ""}') #系统负载
cpu_load_number=$(uptime | awk -F"load average:" '{print $2}' | awk -F"," '{print $1}' | awk -F"." '{print $1}' |sed 's/^[ \t]*//g') #获取近1分钟占用CPU内核数
cpu_user_space=$(top -d 2 -n 1 -b|grep 'C[Pp][Uu]'|head -1|awk -F "[:,]" '{print $2}'|awk -F" " '{print $1}') #用户空间占用CPU的百分比
cpu_system_space=$(top -d 2 -n 1 -b|grep 'C[Pp][Uu]'|head -1|awk -F "[:,]" '{print $3}'|awk -F" " '{print $1}') #内核空间占用CPU的百分比
cpu_idle=$(top -d 2 -n 1 -b|grep C[Pp][Uu]|grep id|awk -F"," '{print $4}'|awk -F" " '{print $1}') #空闲CPU
cpu_wait=$(top -d 2 -n 1 -b|grep 'C[Pp][Uu]'|head -1|awk -F "[:,]" '{print $6}'|awk -F" " '{print $1}') #等待占用CPU的百分比
Pem_totle_m=$(free -m |grep "Mem" |awk -F" " '{print $2"M"}') #实际总物理内存M
Mem_free_m=$(free -m |grep "Mem" |awk -F" " '{print $4"M"}') #实际可用内存M
Mem_used=$(top -d 2 -n 1 -b|grep "Mem"|head -1|sed 's/[:,]/ /g'|awk -F" " '{print $7}'|awk '{printf("%dM\n",$1/1024)}') #用户缓存容量
Mem_free=$( top -d 2 -n 1 -b|grep "Mem"|head -1|sed 's/[:,]/ /g'|awk -F" " '{print $5}'|awk '{printf("%dM\n",$1/1024)}') #空闲缓存容量
Mem_buffer=$(top -d 2 -n 1 -b|grep "Mem"|head -1|sed 's/[:,]/ /g'|awk -F" " '{print $9}'|awk '{printf("%dM\n",$1/1024)}') #缓冲缓存容量
Swap_total=$(top -d 2 -n 1 -b|grep "Swap"|awk -F" " '{print $3}'|awk '{printf("%dM\n",$1/1024)}') #交换分区总容量
Swap_free=$(top -d 2 -n 1 -b|grep "Swap"|awk -F" " '{print $5}'|awk '{printf("%dM\n",$1/1024)}') #交换分区空闲容量
Swap_used=$(top -d 2 -n 1 -b|grep "Swap"|awk -F" " '{print $7}'|awk '{printf("%dM\n",$1/1024)}') #交换分区占用容量
Swap_avail=$(top -d 2 -n 1 -b|grep "Swap"|awk -F" " '{print $9}'|awk '{printf("%dM\n",$1/1024)}') #交换分区可用容量
rx_pck=$(sar -n DEV 1 1 |sed '1,4d'|sed '2,$d'|awk -F" " '{print $3}') #网卡1每秒接收数据包数
tx_pck=$(sar -n DEV 1 1 |sed '1,4d'|sed '2,$d'|awk -F" " '{print $4}') #网卡1每秒发送数据包数
rx_kB=$(sar -n DEV 1 1 |sed '1,4d'|sed '2,$d'|awk -F" " '{print $5}') #网卡1每秒接收字节数
tx_kB=$(sar -n DEV 1 1 |sed '1,4d'|sed '2,$d'|awk -F" " '{print $6}') #网卡1每秒发送字节数
echo -e "系统版本|$OS
系统内核|$Kernel
主机名称|$Hostname
默认语言|$Default_lang
当前时间|$Time
此用户登录时间|$Logintime
系统已运行时间|$Uptime
IP地址|$Ipaddr
掩码|$Netmask
CPU信息|$cpu_info
CPU型号|$cpu_type
CPU架构|$cpu_arch
物理CPU数|$cpu_number_physical
逻辑CPU数|$cpu_number_vir
每CPU核心数|$cpu_cores
单内存容量|$Sigle_memory_capacity
最大存储容量|$Maximum_memory_capacity
内存卡槽数|$Number_of_memory_slots
理论总内存|$Memory_total
内存品牌|$Product_name
总进程数|$Process_numbers
活跃进程数|$Process_running
睡眠进程数|$Process_sleeping
停止进程数|$Process_stoping
僵尸进程数|$Process_zombie
系统负载|$cpu_load
获取近1分钟占用CPU内核数|$cpu_load_number
用户空间占用CPU的百分比|$cpu_user_space
内核空间占用CPU的百分比|$cpu_system_space
空闲CPU|$cpu_idle
等待占用CPU的百分比|$cpu_wait
实际总物理内存M|$Pem_totle_m
实际可用内存M|$Mem_free_m
用户缓存容量|$Mem_used
空闲缓存容量|$Mem_free
缓冲缓存容量|$Mem_buffer
交换分区总容量|$Swap_total
交换分区空闲容量|$Swap_free
交换分区占用容量|$Swap_used
交换分区可用容量|$Swap_avail
网卡1每秒接收数据包数|$rx_pck
网卡1每秒发送数据包数|$tx_pck
网卡1每秒接收字节数|$rx_kB
网卡1每秒发送字节数|$tx_kB"
}

#获取磁盘状态信息
function get_disk_status(){
echo -e "#磁盘使用情况:"
	IFS="
		"
	for i in ` df -iP | sed 1d | awk '{print $(NF-1)"\t"$NF"\t"$(NF-2)}'`;do
	DISK_UTILIZ=$( echo $i |awk '{print $1}') #利用率
	MOUNT_DISK=$(echo $i |awk '{print $2}') #挂载点
	DISK_FREE=$(echo $i |awk '{print $3}') #分区大小
	if [[ $(echo $MOUNT_DISK | sed s/%//g) -gt 70 ]];then
	echo "异常""("$MOUNT_DISK"使用率为"$DISK_UTILIZ",超过70%)"
	else
		continue
	fi
	done
df -hP |sed 1d |awk '{print $NF" ""分区"" ""剩余空间"" "$(NF-2),"使用率"" "$(NF-1)}'
}

#获取CPU状态
function get_cup_status(){
echo -e "#CPU状态"
cpu_number=$(cat /proc/cpuinfo |grep name |cut -d: -f2 |uniq -c |awk '{print $1}') #提取CPU核数
cpu_load_number=$(uptime | awk -F"load average:" '{print $2}' | awk -F"," '{print $1}' | awk -F"." '{print $1}' |sed 's/^[ \t]*//g') #获取近1分钟占用CPU内核数
if [[ $cpu_load_number -lt $cpu_number ]];then
	CPU_STATUS=正常
else
	CPU_STATUS=异常
fi
}

#获取内存状态
function get_memory_status(){
echo -e "#内存状态:"
MEM_TOTLE=$(free -m |grep "Mem" |awk -F" " '{print $2}') #总物理内存
MEM_FREE=$(free -m |grep "Mem" |awk -F" " '{print $4}') #可用内存
MEM_TOTLE_M=$(free -m |grep "Mem" |awk -F" " '{print $2"M"}') #总物理内存M
MEM_FREE_M=$(free -m |grep "Mem" |awk -F" " '{print $4"M"}') #可用内存M
MEM_USED=$(echo $(($MEM_TOTLE-$MEM_FREE))) #总占用内存
PERCENT=$(printf "%d%%" $(($MEM_USED*100/$MEM_TOTLE))) #内存占用率
PERCENT_N=$(echo $PERCENT|sed s/%//g) #内存占用率数值
if [[ $PERCENT_N -lt 80 ]];then
	MEM_STATUS=正常
else
	MEM_STATUS=异常
fi
echo -e "$MEM_STATUS\n"总内存大小:"$MEM_TOTLE_M,"剩余内存大小:"$MEM_FREE_M,"内存使用率"$PERCENT"
}

#检测是否存在暴力破解密码
function get_ssh_deny(){
echo -e "#是否存在暴力破解密码:"
SYSTEM_TYPE=$(head -n 1 /etc/os-release |awk -F"=" '{print $2}'|awk -F" " '{print $1}'|sed 's/"//g') #获取系统类型
if [[ $SYSTEM_TYPE = 'CentOS' ]];then
	SSH_SUM=$(cat /var/log/secure |grep "authentication failure" |wc -l)
	SSH_DIY=10
	if [[ $SSH_SUM -gt $SSH_DIY ]];then
		echo ""请注意,密码尝试次数为"$SSH_SUM"
	else
		echo "正常"
	fi
else
	echo "系统类型不支持"
fi
}

#检查开机自启任务
function get_auto_start_status() {
echo -e "#开机自启任务"
conf=$(grep -v "^#" /etc/rc.d/rc.local | sed '/^$/d')
echo "$conf"
}

#检查可登陆用户与无密码的用户
function get_user(){
echo -e "#可登陆用户与无密码的用户:"
/usr/bin/w #当前在线用户信息
user=$(cat /etc/passwd|awk -F":" '$7 ~"/bin/bash"{print $1}') #可登陆用户
echo -e "可登陆用户:\n$user"
echo "未设置密码用户:"
for i in $user ;do
cat /etc/shadow|grep $i|awk -F":" '$2 ~"!!"{print $1,$2}' #未设置密码的用户
done
}

#检查计划任务
function get_corn(){
echo -e "#计划任务:"
user=` cat /etc/passwd |awk -F":" '$7 ~"/bin/bash"{print $1}' ` #获取用户列表
for cronuser in $user;do
	crontab -l -u $cronuser > /dev/null 2>&1
	if [ $? -eq 0 ];then
		echo "$cronuser"
		echo "######"
		crontab -l -u $cronuser | grep -vE "^#|^$"
		echo "######"
	else
		echo "用户$cronuser不存在计划任务"
	fi
done
}

#检查进程状态
function get_process(){
echo -e "#是否存在僵尸进程:"
if  [[ $(ps -aux | grep Zs |grep -v grep | wc -l ) -ge 1 ]];then #检查僵尸进程是否存在
	echo "存在僵尸进程"
	ps -aux |grep Zs |grep -v grep #输出僵尸进程信息
else
	echo "不存在僵尸进程"
fi
echo -e "内存占用率TOP10进行列表:"
ps aux | awk '{print $2, $4, $6, $11}' | sort -k3rn | head -n 10 #获取内存占用率TOP10进行列表
echo -e "CPU利用率TOP10进行列表:"
top b -n1 | head -17 | tail -11 #获取CPU利用率TOP10进行列表
}

#获取系统巡检信息并写入本地巡检日志
function check_gather_log(){
if [ ! -x "$local_log_path" ];then #判断本地日志存储路径是否存在
    mkdir "$local_log_path" #创建本地日志存储路径
fi
if [ -f "$local_log_path/$LogName.log" ];then #判断日志文件是否存在
	rm -rf $local_log_path/$LogName.log #删除已存在日志文件
fi
touch $local_log_path/$LogName.log #创建日志文件
get_status>>$local_log_path/$LogName.log #调用对应方法并将巡检结果写入日志文件
get_disk_status>>$local_log_path/$LogName.log
get_cup_status>>$local_log_path/$LogName.log
get_memory_status>>$local_log_path/$LogName.log
get_ssh_deny>>$local_log_path/$LogName.log
get_auto_start_status>>$local_log_path/$LogName.log
get_user>>$local_log_path/$LogName.log
get_corn>>$local_log_path/$LogName.log
get_process>>$local_log_path/$LogName.log
}

#执行巡检
check_gather_log

#执行日志回传
scp_log_to_main_server="scp $local_log_path/$LogName.log root@$main_ipaddr:$main_log_path"

#调用Expect工具辅助日志回传的密码验证过程
/usr/bin/expect<<EOF
	set timeout 20
	spawn $scp_log_to_main_server
	expect {
		"*yes/no)?" 
		{ 
			send "yes\n"
			"*password:*" {send "main_passwd\n"}
		} 
		"*password:"         
		{
			send "$main_passwd\n"
		}
	}
	expect "*password:"  { send "$main_passwd\n" }
	expect "100%"
	expect eof
EOF

4.1、脚本准备

设置文件可执行权限:

chmod +x check_command.sh

复制文件至目标路径:

cp check_command.sh /tmp/check_script/

5、下发脚本实现

5.1、在目标服务器上创建脚本存储路径

文件名:check_expect_mkdir.sh

#!/usr/bin/expect
set timeout 30
set server_ip [lindex $argv 0]
set server_passwd [lindex $argv 1]
set CheckScriptPath [lindex $argv 2]

spawn ssh -o StrictHostKeyChecking=no root@$server_ip
	expect {
		"*yes/no)?" 
		{ 
			send "yes\n"
			"*password:*" {send "server_passwd\n"}
		} 
		"*password:*"         
		{
			send "$server_passwd\n"
		}
	}
	expect "*password:*"  { send "$server_passwd\n" }
	expect "*#" { send "mkdir $CheckScriptPath\n"}
	expect eof
exit

5.2、将巡检脚本下发至目标服务器

文件名:check_expect_upload.sh

#!/usr/bin/expect
set timeout 20
set server_ip [lindex $argv 0]
set server_passwd [lindex $argv 1]
set check_script_path [lindex $argv 2]

spawn scp $check_script_path/check_command.sh root@$server_ip:$check_script_path
	expect {
		"*yes/no)?" 
		{ 
			send "yes\n"
			"*password:*" {send "server_passwd\n"}
		} 
		"*password:*"         
		{
			send "$server_passwd\n"
		}
	}
	expect "*password:*"  { send "$server_passwd\n" }
	expect "100%"
	expect eof
exit

5.3、在目标服务器上执行巡检脚本

文件名:check_expect_do.sh

#!/usr/bin/expect	
set timeout 20
set server_ip [lindex $argv 0]
set server_passwd [lindex $argv 1]
set check_script_path [lindex $argv 2]
set main_ipaddr [lindex $argv 3]
set main_passwd [lindex $argv 4]

spawn  ssh -o StrictHostKeyChecking=no root@$server_ip
	expect {
		"*yes/no)?" 
		{ 
			send "yes\n"
			"*password:*" {send "server_passwd\n"}
		} 
		"*password:"         
		{
			send "$server_passwd\n"
		}
	}
	expect "*password:"  { send "$server_passwd\n" }
	expect "*#" { send "cd $check_script_path;./check_command.sh $main_ipaddr $main_passwd\n" }
	expect eof
exit

5.4、控制脚本下发与执行

文件名:check_ctrl2.sh

#!/bin/bash
#
#加载参数
login_info=$1 #参数1,待巡检服务器文件
main_ipaddr=$2 #参数2,日志上传目标服务器IP地址
main_passwd=$3 #参数3,日志上传目标服务器登陆密码 
main_log_path="/tmp/checklog_directory" #日志上传目标服务器日志存储路径
check_script_path="/tmp/check_script" #巡检脚本文件存储路径

#检测参数数量,如果参数数量异常则输出提示
if [ $# -ne 3 ];then
	echo -e "parameters if fault!\n"
	exit;
fi

#解析登陆列表
cat $login_info |while read line
do
server_ip=` echo $line |awk '{print $1}' ` #读取目标服务器IP
server_passwd=` echo $line |awk '{print $2}' ` #读取目标服务器密码

echo -e "\n######当前服务器:$server_ip######\n"

./check_expect_mkdir.sh $server_ip $server_passwd $check_script_path #创建脚本存储路径

./check_expect_upload.sh $server_ip $server_passwd $check_script_path #下发测试脚本

./check_expect_do.sh $server_ip $server_passwd $check_script_path $main_ipaddr $main_passwd #执行巡检脚本

done

6、测试执行

脚本执行:

./check_ctrl2.sh server_info_file.txt 192.168.52.3 123456


执行结果:

日志内容:

Yunxi.D
2020/02/14

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux服务器Shell批量巡检 的相关文章

  • Docker忽略limits.conf(试图解决“打开文件太多”错误)

    我正在运行一个 Web 服务器 该服务器正在处理数千个并发 Web 套接字连接 为了实现这一点 在 Debian linux 我的基本镜像是 google debian wheezy 在 GCE 上运行 上 打开文件的默认数量设置为 100
  • 为什么此 NASM 代码会打印我的环境变量?

    本学期我刚刚完成计算机体系结构课程 除其他外 我们一直在涉足 MIPS 汇编并在 MARS 模拟器中运行它 今天 出于好奇 我开始在我的 Ubuntu 机器上摆弄 NASM 基本上只是将教程中的内容拼凑起来 并感受一下 NASM 与 MIP
  • 如何在 Linux 和 C 中使用文件作为互斥体?

    我有不同的进程同时访问 Linux 中的命名管道 并且我想让此访问互斥 我知道可以使用放置在共享内存区域中的互斥体来实现这一点 但作为一种家庭作业 我有一些限制 于是 我想到的是对文件使用锁定原语来实现互斥 我做了一些尝试 但无法使其发挥作
  • 如何使用 git hook pre-merge-commit 获取原始合并分支名称

    我正在尝试使用新的 git hook pre merge commit 创建一个特定的脚本 但它没有参数 有什么解决方法可以让我获得正在合并的分支的名称吗 例子 在分支 myBranch 上 我调用 git merge testingBra
  • unix 下日期字段排序

    我有包含数十万条记录的文本文件 其中一个字段是日期字段 有没有办法根据日期字段对文件进行排序 09 APR 12 04 08 43 632279000 AM 19 MAR 12 03 53 38 189606000 PM 19 MAR 12
  • 为 Linux 编译 Objective-C 应用程序(API 覆盖范围)

    我可能在这里问一些奇怪的问题 但我不确定从哪里开始 问题是我正在考虑使用 Obj C 和 Foundation 类在 Mac 上编写一个命令行工具 但存在一个非常大的风险 那就是我希望能够为不同的 Linux 发行版编译它 以便将来作为服务
  • Ubuntu Python shebang 线不工作

    无法让 shebang 线在 Ubuntu 中为 python 脚本工作 我每次只收到命令未找到错误 test py usr bin env python print Ran which python usr bin python 在 sh
  • 如何在线程创建和退出时调用函数?

    include
  • 如何在 Linux 上通过 FTP 递归下载文件夹 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • Bash 中所有匹配的^单词^替换^?

    为了澄清 我正在寻找一种方法来执行global搜索并替换先前使用的命令 word replacement 似乎只替换了第一场比赛 有没有一些set我无法选择的选项 尝试这个 echo oneone oneone gs one two Rep
  • 如何在不使用 IDE 的情况下在 Linux 上运行 Java 项目

    我是 Java 新手 基本上 我开发了一个java项目 其中包含Eclipse中的多个Java包 该项目在我安装了 redhat Linux 的桌面上运行正常 然而 我需要在一个更强大的没有安装X11的Linux服务器 redhat ent
  • grep 排除文件的数组参数

    我想从我的文件中排除一些文件grep命令 为此我使用参数 exclude excluded file ext 为了更容易阅读 我想使用包含排除文件的 bash 数组 EXCLUDED FILES excluded file ext 然后将
  • 为什么 Linux 原始套接字的 RX 环大小限制为 4GB?

    背景 我试图mmap 我的原始套接字的 RX 环形缓冲区64 bitLinux 应用程序 我的环由 4096 个块组成 每个块大小为 1MB 总共 4GB 请注意 每个 1MB 块中可以有许多帧 如果您好奇 请参阅此文档了解背景信息 htt
  • Linux 中 m 标志和 o 标志将存储在哪里

    我想知道最近收到的路由器通告的 m 标志和 o 标志的值 从内核源代码中我知道存储了 m 标志和 o 标志 Remember the managed otherconf flags from most recently received R
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • 为什么 Linux 没有 DirectX API?

    在考虑现代显卡的 Windows 系统上 DirectX API 的驱动程序端实现时 我想知道为什么此实现在非 Windows 系统 尤其是 Linux 上不可用 由于明显缺乏此功能 我只能假设有一个我无视的充分理由 但在我的原始理解中 我
  • 适用于 Linux 的轻量级 IDE [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 调用 printf 系统子例程在汇编代码中输出整数错误[重复]

    这个问题在这里已经有答案了 来回 在windows7控制台窗口中运行gcc s2 asm 然后生成一个exe文件 运行a exe 然后崩溃 为什么 s2 asm 代码由以下源代码生成 int m m 1 iprint m s2 asm请参考
  • 如何从 LaTeX 执行 shell 脚本?

    我正在尝试在 LaTeX 中执行以下操作 documentclass article begin document execute usr local bin my shell script sh end document 想法是执行 us
  • 在 .gitconfig 中隐藏 GitHub 令牌

    我想将所有点文件存储在 GitHub 上 包括 gitconfig 这需要我将 GitHub 令牌隐藏在 gitconfig 中 为此 我有一个 gitconfig hidden token 文件 这是我打算编辑并放在隐藏令牌的 git 下

随机推荐