M - Find a way

博客讲述yifenfei回到宁波与好友Merceki相约KFC碰面,要选一个使两人总用时最短的KFC。给出宁波地图,两人可上下左右移动,每移动一格耗时11分钟。还给出输入输出格式及示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki.
Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest.
Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes.
Input
The input contains multiple test cases.
Each test case include, first two integers n, m. (2<=n,m<=200).
Next n lines, each line included m character.
‘Y’ express yifenfei initial position.
‘M’ express Merceki initial position.
‘#’ forbid road;
‘.’ Road.
‘@’ KCF
Output
For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.
Sample Input
4 4
Y.#@

.#…
@…M
4 4
Y.#@

.#…
@#.M
5 5
Y…@.
.#…
.#…
@…M.
#…#
Sample Output
66
88
66

#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
typedef struct
{
	int x,y;
	int s;
}N;
N Y,M;
int n,m;
int vis[320][320];
char mise[320][320];
int res[320][320][5];
int d[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
void bfs(N t,int num)
{
	queue<N>q;
    q.push(t);
	memset(vis,0,sizeof(vis));
	vis[t.x][t.y]=1;
	N no,nn;
	while(q.size())
	{
      no=q.front();
	  q.pop();
	  if(mise[no.x][no.y]=='@')
	    res[no.x][no.y][num]=no.s;
	  for(int i=0;i<4;i++)
	  {
		  nn.x=no.x+d[i][0];
		  nn.y=no.y+d[i][1];
          nn.s=no.s+1;
		  if(nn.x>=0&&nn.x<n&&nn.y>=0&&nn.y<m&&!vis[nn.x][nn.y]&&mise[nn.x][nn.y]!='#')
		  {
			  vis[nn.x][nn.y]=1;
			   q.push(nn);
		  }
	  }
	}
}
int main()
{
	int i,j;
	while(cin>>n>>m)
	{ 
		for(i=0;i<n;i++)
		{
			 cin>>mise[i];
			 for(j=0;j<m;j++)
			 {
				 if(mise[i][j]=='Y')
				 {
					 Y.x=i;
					 Y.y=j;
					 Y.s=0;
				 }
				 if(mise[i][j]=='M')
				 {
					 M.x=i;
					 M.y=j;
                     M.s=0;
				 }
			 }
		 }
		 memset(res,0,sizeof(res));
		 bfs(Y,0);
		 bfs(M,1);
		 int ans=0x3f3f3f;
		 for(i=0;i<n;i++)
		 {
			 for(j=0;j<m;j++)
			 {
                if(res[i][j][0]&&res[i][j][1])
				ans=min(ans,res[i][j][0]+res[i][j][1]);
			 }
		 }
		 cout<<ans*11<<endl;
	}
	return 0;
}
#!/bin/bash #source ~/.bashrc source /etc/profile #本文作用:当前目录下所有jar的启动-重启-停止-findall等操作 #tset.sh stop -a (如果该JAR包已启动则先杀后启) #主要指令 分为 start(启动) stop(停止) 如果没写 则默认start #次要指令 -x {纯数字} (非必填) 设置JVM -a 启动当前文件夹下所有jar包(非必填) #方式1已验证成功 ./test123.sh startfile/stopfile/restartfile/ 根据事先写好的test1111.sh内容进行启动 #方式2已验证成功 ./test123.sh startall/stopall/restartall/ 根据当前路径下所有jar包进行启动 #命令3已验证成功 ./test123.sh c8085.jar(如果没起就起,如果已起就重启) #命令4已验证成功 ./test123.sh findall(查找出当前目录下所有*.jar格式的包) #备注:需要将di2lie里边的grep -v test123 改成启动文件名。 #test.sh {主要指令} echo "启动qidong" # 1启动 2停止 3重启 export JVM_XM="-Xms256 -Xmx256" export JAR_NAMES export JAR_PID #export java_path=`echo $JAVA_HOME` java_path=$(dirname $(dirname $(readlink -f $(which javac)))) #export java_path=`/home/jdk1.8.0_281` export pids=`ps -ef | grep $* | grep -v grep | awk '{print $2}'| xargs` export di1lie=`ps -ef | grep $* | grep -v 'grep' | awk '{print $1}' | xargs` export di2lie=`ps -ef | grep $* | grep -v "grep" | grep -v start123 | awk '{print $2}' | xargs` ##export aaa=($(find . -type f -name "*.jar" |sed 's#^\./##' |grep -v "/")) #当前文件夹下所有jar,暂时不用,但aaa的结果是对的 export FILE_NAME=($(find *.jar | awk '{print $1 ""}')) #当前文件夹所有jar export java_id=$(ps -ef|grep java |grep -v grep |awk '{print $2}') #-x 设置JVM 暂时未实现 #-a 启动当前文件夹全部jar包 已实现 ./test123.sh startall for arg in $*; do case $arg in #方式1 "startfile") #JAR_NAMES[${#JAR_NAMES[@]}]=$arg echo "startfile";; "stopfile") #JAR_NAMES[${#JAR_NAMES[@]}]=$arg echo "stopfile";; "restartfile") #JAR_NAMES[${#JAR_NAMES[@]}]=$arg echo "restartfile";; #方式2 "startall") #JAR_NAMES[${#JAR_NAMES[@]}]=$FILE_NAME echo "startall";; "stopall") #JAR_NAMES[${#JAR_NAMES[@]}]=$FILE_NAME echo "stopall";; "restartall") #JAR_NAMES[${#JAR_NAMES[@]}]=$FILE_NAME echo "restartall";; #命令3 *".jar") #JAR_NAMES[${#JAR_NAMES[@]}]=$arg echo ".jar";; #命令4 "findall") #JAR_NAMES[${#JAR_NAMES[@]}]=$FILE_NAME echo "findall";; esac done for name in ${JAR_NAMES[*]} do #$pids=`ps -ef | grep java | grep -v "grep" | awk '{print $2}'` # echo "${JAR_NAMES[*]} 000000000000000000" echo "000000000000000000" done for pid in $arg do case $arg in #方式1 "startfile") . ./test1111.sh #JAR_PID[${#JAR_PID[@]}]=`ps -ef | grep java | grep -v grep | awk '{print $2}' | xargs` pids=`ps -ef | grep java | grep -v "grep" | awk '{print $2}'` ;; "stopfile") pids=`ps -ef | grep java | grep -v "grep" | awk '{print $2}'` kill -9 $pids;; #JAR_PID[${#JAR_PID[@]}]=`ps -ef | grep java | grep -v grep | awk '{print $2}' | xargs` #kill -9 $JAR_PID;; "restartfile") pids=`ps -ef | grep java | grep -v "grep" | awk '{print $2}'` kill -9 $pids . ./test1111.sh;; #方式2 "startall") for i in ${!FILE_NAME[*]}; do jar_id=`(ps -ef | grep ${FILE_NAME[i]} | grep -v "grep" | grep -v start123 | awk '{print $2}' | xargs )` #进程 if [[ ( ${FILE_NAME[i]} == *"-comprehensive.jar"*) ]]; then #comprehensive包 if [[ ( $jar_id != "" ) ]]; then #起了就不起 echo "${FILE_NAME[i]} is already started! the process is $jar_id/" fi if [[ ( $jar_id == "" ) ]]; then #没起就起 nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms1500M -Xmx1500M -jar "${FILE_NAME[i]}" > "${FILE_NAME[i]}.log" 2>&1 & echo "${FILE_NAME[i]} is start readay!" fi elif [[ ( ${FILE_NAME[i]} == *"-auc.jar"*) ]]; then #auc包 if [[ ( $jar_id != "" ) ]]; then #起了就不起 echo "${FILE_NAME[i]} is already started,the process is $jar_id/" fi if [[ ( $jar_id == "" ) ]]; then #没起就起 nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms500M -Xmx500M -jar "${FILE_NAME[i]}" > "${FILE_NAME[i]}.log" 2>&1 & echo "${FILE_NAME[i]} is start readay!" fi else if [[ ( $jar_id != "" ) ]]; then #起了就不起 echo "${FILE_NAME[i]} is already started,the process is $jar_id/" fi if [[ ( $jar_id == "" ) ]]; then #没起就起 nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms256M -Xmx256M -jar "${FILE_NAME[i]}" > "${FILE_NAME[i]}.log" 2>&1 & echo "${FILE_NAME[i]} is start readay!" fi fi printf "\n" done ;; "stopall") abc=$(pwd) #shell脚本里。获取当前路径值赋值给abc echo "pwd:$(pwd)" for id in ${java_id[*]}; do exe_path=$(readlink /proc/$id/cwd) if [[ "$exe_path" == "$abc" ]];then #echo "id=$id~~~~~~~~~~~" kill -9 $id echo "$id is killed" else echo "the process:$id start way is not in $abc ,the way is in $exe_path" fi; done ;; "restartall") abc=$(pwd) #shell脚本里。获取当前路径值赋值给abc for id in ${java_id[*]}; do exe_path=$(readlink /proc/$id/cwd) if [[ "$exe_path" == "$abc" ]];then kill -9 $id echo "$id is killed" else echo "the process:$id start way is not in $abc , the way is in $exe_path" fi; done for i in ${!FILE_NAME[*]}; do if [[ ( ${FILE_NAME[i]} == *"-comprehensive.jar"*) ]]; then #comprehensive包 if [[ ($di1lie=="root root root" )&&( $di2lie != "" )]] ; then #comprehensive起了,先杀再起 kill -9 $di2lie nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms1500M -Xmx1500M -jar $abc/${FILE_NAME[i]} > $abc/${FILE_NAME[i]}.log 2>&1 & echo "$di2lie is start ready!" fi if [[ ( $di1lie == "root root" )&&( $di2lie == "" ) ]]; then #comprehensive没起,就起 nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms1500M -Xmx1500M -jar $abc/${FILE_NAME[i]} > $abc/${FILE_NAME[i]}.log 2>&1 & echo "${FILE_NAME[i]} is start readay!" fi elif [[ ( ${FILE_NAME[i]} == *"-auc.jar"*) ]]; then #auc包 if [[ ($di1lie=="root root root" )&&( $di2lie != "" )]] ; then #auc起了,先杀再起 kill -9 $di2lie nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms500M -Xmx500M -jar $abc/${FILE_NAME[i]} > $abc/${FILE_NAME[i]}.log 2>&1 & echo "${FILE_NAME[i]} is start ready!" fi if [[ ( $di1lie == "root root" )&&( $di2lie == "" ) ]]; then #auc没起,就起 nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms500M -Xmx500M -jar $abc/${FILE_NAME[i]} > $abc/${FILE_NAME[i]}.log 2>&1 & echo "${FILE_NAME[i]} is start readay!" fi else #其他包 if [[ ($di1lie=="root root root" )&&( $di2lie != "" ) ]]; then #起了先杀再起111 kill -9 $di2lie nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms256M -Xmx256M -jar $abc/${FILE_NAME[i]} > $abc/${FILE_NAME[i]}.log 2>&1 & echo "${FILE_NAME[i]} is restart readay!" fi if [[ ( $di1lie == "root root" )&&( $di2lie == "" ) ]]; then #没起就起 nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms256M -Xmx256M -jar $abc/${FILE_NAME[i]} > $abc/${FILE_NAME[i]}.log 2>&1 & echo "${FILE_NAME[i]} is start readay!" fi fi done ;; #命令3 *".jar") abc=$(pwd) if [[ ($* == *-comprehensive.jar*) ]]; then #comprehensive包 if [[ ($di1lie=='root root root' )&&( $di2lie != '' )]] ; then #comprehensive起了,先杀再起 kill -9 $di2lie nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms1500M -Xmx1500M -jar "$abc/$*" > "$abc/$*.log" 2>&1 & echo "$arg is start ready!" fi if [[ ( $di1lie == 'root root' )&&( $di2lie == '' ) ]]; then #comprehensive没起,就起 nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms1500M -Xmx1500M -jar "$abc/$*" > "$abc/$*.log" 2>&1 & echo "$* is start readay!" fi elif [[ ($* == *-unify.jar*) ]]; then #unify包 if [[ ($di1lie=='root root root' )&&( $di2lie != '' )]] ; then #unify起了,先杀再起 kill -9 $di2lie nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms500M -Xmx500M -jar "$abc/$*" > "$abc/$*.log" 2>&1 & echo "$arg is start ready!" fi if [[ ( $di1lie == 'root root' )&&( $di2lie == '' ) ]]; then #unify没起,就起 nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms500M -Xmx500M -jar "$abc/$*" > "$abc/$*.log" 2>&1 & echo "$* is start readay!" fi elif [[ ($* == *-auc.jar*) ]]; then #auc包 if [[ ($di1lie=='root root root' )&&( $di2lie != '' )]] ; then #auc起了,先杀再起 kill -9 $di2lie nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms500M -Xmx500M -jar "$abc/$*" > "$abc/$*.log" 2>&1 & echo "$arg is start ready!" fi if [[ ( $di1lie == 'root root' )&&( $di2lie == '' ) ]]; then #auc没起,就起 nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms500M -Xmx500M -jar "$abc/$*" > "$abc/$*.log" 2>&1 & echo "$* is start readay!" fi else #其他包 if [[ ($di1lie=='root root root' )&&( $di2lie != '' ) ]]; then #起了先杀再起111 kill -9 $di2lie nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms256M -Xmx256M -jar "$abc/$*" > "$abc/$*.log" 2>&1 & echo "$* is restart readay!" fi if [[ ( $di1lie == 'root root' )&&( $di2lie == '' ) ]]; then #没起就起 nohup $java_path/bin/java -Dfile.encoding=utf-8 -Xms256M -Xmx256M -jar "$abc/$*" > "$abc/$*.log" 2>&1 & echo "$* is start readay!" fi fi ;; #命令4 "findall") echo "$(pwd)/下有如下包:" for i in ${!FILE_NAME[*]}; do echo "${FILE_NAME[i]}" done printf "\n" echo "$(pwd)/下未启动的包有:" for i in ${!FILE_NAME[*]}; do no_id=$(ps -ef | grep ${FILE_NAME[i]} | grep -v "grep" | grep -v start123 | awk '{print $2}' | xargs) if [[ -z "${no_id}" ]]; then echo "${FILE_NAME[i]}!" fi done printf "\n" echo "$(pwd)/下启动的包有:" for i in ${!FILE_NAME[*]}; do no_id=$(ps -ef | grep ${FILE_NAME[i]} | grep -v "grep" | grep -v start123 | awk '{print $2}' | xargs) if [[ ! -z "${no_id}" ]]; then echo "${FILE_NAME[i]}已启动,进程ID为${no_id}" fi done esac done printf "\n" echo "结束jieshu" 如何让这个脚本,让通过ssh执行的这个脚本时,脚本能正确获取java环境
最新发布
07-31
<think>我们注意到脚本中使用了`readlink -f $(which javac)`来获取Java路径,这通常可以找到Java安装路径。但是,在通过SSH执行时,环境变量可能与交互式Shell不同,特别是当`.bashrc`或`/etc/profile`中设置了环境变量时。 问题分析: 1. 在SSH执行时,默认是非交互式、非登录Shell,因此不会加载`~/.bashrc`(除非SSH配置为启动登录Shell)或`/etc/profile`(对于登录Shell)。 2. 脚本开头尝试加载`/etc/profile`,这可以确保系统级的环境变量被加载。但是,用户级别的环境变量(如`~/.bashrc`中的设置)可能不会被加载。 解决方案: 为了确保Java环境变量正确设置,我们可以采取以下措施: 1. 在脚本中显式设置`JAVA_HOME`(如果知道路径),或者使用绝对路径调用Java。 2. 或者,在脚本中尝试从常见的环境文件加载环境变量(如`/etc/profile`和用户目录下的`.bashrc`),但要注意非交互式Shell不会自动加载这些文件。 但是,由于脚本已经尝试加载了`/etc/profile`,这应该可以获取系统级的Java设置(如果`/etc/profile`中设置了`JAVA_HOME`)。然而,如果Java是通过用户级别的配置(如`~/.bashrc`)设置的,那么可能不会生效。 改进建议: 我们可以尝试在脚本中加载用户目录下的`.bashrc`(如果存在),但要注意`.bashrc`可能包含一些仅用于交互式Shell的设置,这可能会导致问题。因此,我们可以有选择地加载环境变量。 另一种方法是:在SSH命令中指定环境变量,或者让SSH启动一个登录Shell(这样会加载用户的环境设置)。例如: ssh user@host "source ~/.bashrc; /path/to/script.sh" 但是,如果希望脚本自身能够适应,我们可以尝试在脚本中判断并加载用户的环境文件。 然而,在脚本中,我们更倾向于使用绝对路径来避免依赖环境变量。例如,如果我们知道Java安装路径,可以直接使用绝对路径。 但是,脚本中已经使用以下方式获取Java路径: java_path=$(dirname $(dirname $(readlink -f $(which javac)))) 这个命令在大多数情况下是有效的,因为它通过`which javac`找到`javac`的路径,然后解析其真实路径,再向上两级得到Java安装目录。 问题在于:在非交互式Shell中,`which`命令可能无法找到`javac`,因为PATH环境变量可能没有设置。 因此,我们需要确保PATH被正确设置。由于脚本开头已经加载了`/etc/profile`,这通常设置了系统级的PATH。如果还不够,我们可以尝试加载用户的环境文件。 修改脚本开头: # 加载系统配置文件 source /etc/profile # 加载当前用户的环境配置文件(如果存在) if [ -f ~/.bash_profile ]; then source ~/.bash_profile elif [ -f ~/.bash_login ]; then source ~/.bash_login elif [ -f ~/.profile ]; then source ~/.profile elif [ -f ~/.bashrc ]; then source ~/.bashrc fi 这样,在SSH执行时,脚本会尝试加载用户的环境设置,从而正确设置PATH。 但是,注意:如果这些文件中有输出(例如echo),可能会导致脚本输出不必要的日志。因此,我们需要确保这些环境文件在非交互式Shell中运行时不会产生输出。 另外,我们也可以考虑在脚本中直接设置PATH,例如: export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 然后再加上我们需要的路径(如Java的bin目录)。 然而,最可靠的方法还是使用绝对路径调用Java。但我们的脚本中已经通过`which javac`来定位Java,所以只要PATH正确,就能找到。 因此,修改脚本开头,增加加载用户环境文件的代码。 但是,注意:在SSH执行时,用户环境文件中的命令可能会失败(因为非交互式),或者产生输出。因此,我们可以尝试静默加载。 修改后的脚本开头部分: ```bash #!/bin/bash # 加载系统配置文件 source /etc/profile # 加载用户的环境配置文件(如果存在),并重定向错误和输出到/dev/null,避免输出干扰 [ -f ~/.bash_profile ] && source ~/.bash_profile >/dev/null 2>&1 [ -f ~/.bash_login ] && source ~/.bash_login >/dev/null 2>&1 [ -f ~/.profile ] && source ~/.profile >/dev/null 2>&1 [ -f ~/.bashrc ] && source ~/.bashrc >/dev/null 2>&1 # 其他代码... ``` 这样,脚本在SSH执行时应该能正确获取Java环境。 另外,我们注意到脚本中使用了`export java_path=$(dirname $(dirname $(readlink -f $(which javac))))`,这个命令在找不到`javac`时会出错。我们可以添加错误检查: ```bash which javac >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: javac not found. Please ensure Java Development Kit (JDK) is installed and in the PATH." exit 1 fi ``` 但是,为了简化,我们也可以直接使用`java`命令(因为运行jar只需要java,不需要javac)。所以,我们可以改为查找`java`命令的路径: ```bash # 查找java命令的路径 java_bin=$(which java) if [ -z "$java_bin" ]; then echo "Error: java not found. Please ensure Java Runtime Environment (JRE) is installed and in the PATH." exit 1 fi java_path=$(dirname $(dirname $(readlink -f "$java_bin"))) ``` 但是注意,`which java`可能返回多个结果,但通常返回第一个。另外,`readlink -f`可以解析链接。 然而,在脚本中,我们实际使用`$java_path/bin/java`来启动Java。所以,我们可以直接使用找到的`java_bin`(即`$java_bin`)来启动,而不需要再构造路径。 因此,我们可以修改脚本,将`java_bin`作为Java可执行文件的路径: 原代码: nohup $java_path/bin/java ... 改为: nohup $java_bin ... 这样更直接。 修改步骤: 1. 将获取Java路径的部分改为获取`java`的绝对路径。 2. 替换脚本中所有`$java_path/bin/java`为`$java_bin`。 但是,注意:在脚本中,我们使用了`$java_path`来构造`bin/java`,而实际上我们通过`which java`已经得到了`java`的完整路径,所以可以直接使用。 修改后的代码: ```bash # 获取java的绝对路径 java_bin=$(which java) if [ -z "$java_bin" ]; then echo "Error: java not found. Please ensure Java Runtime Environment (JRE) is installed and in the PATH." exit 1 fi # 然后,在启动jar包的地方,使用$java_bin代替$java_path/bin/java ``` 例如: nohup $java_bin -Dfile.encoding=utf-8 -Xms256M -Xmx256M -jar ... 这样,即使Java的安装路径很特殊,也能正确使用。 但是,注意:在脚本中,我们使用了`export java_path`,但后续并没有使用这个变量(除了用来构造`$java_path/bin/java`)。如果我们改为使用`java_bin`,那么`java_path`就可以不用了。 因此,我们重构脚本: 1. 删除`export java_path`的定义,改为`java_bin`。 2. 在需要启动Java的地方,使用`$java_bin`。 另外,我们还需要处理另一个问题:在SSH执行时,`which java`可能还是找不到,因为PATH可能没有设置。所以,我们前面加载环境文件的步骤就很重要。 综合以上,我们修改脚本的开头部分,并替换所有启动Java命令的地方。 由于原脚本较长,我在这里只修改关键部分,并给出修改后的完整脚本开头。 修改后的脚本开头: ```bash #!/bin/bash # 加载系统配置文件 source /etc/profile # 加载用户的环境配置文件(如果存在) [ -f ~/.bash_profile ] && source ~/.bash_profile >/dev/null 2>&1 [ -f ~/.bash_login ] && source ~/.bash_login >/dev/null 2>&1 [ -f ~/.profile ] && source ~/.profile >/dev/null 2>&1 [ -f ~/.bashrc ] && source ~/.bashrc >/dev/null 2>&1 # 获取java的绝对路径 java_bin=$(which java) if [ -z "$java_bin" ]; then echo "Error: java not found. Please ensure Java Runtime Environment (JRE) is installed and in the PATH." exit 1 fi # 其他环境变量设置... export JVM_XM="-Xms256 -Xmx256" export JAR_NAMES export JAR_PID # ... 其余不变 ``` 然后,在启动jar包的地方,将`$java_path/bin/java`替换为`$java_bin`。 例如: nohup $java_bin -Dfile.encoding=utf-8 -Xms256M -Xmx256M -jar ... 注意:原脚本中使用了`$java_path`的地方都要检查,但只有启动Java命令的地方使用了。 由于原脚本很长,这里只给出修改示例,具体修改需要在整个脚本中搜索`$java_path/bin/java`并替换。 另外,原脚本中有一段: export java_id=$(ps -ef|grep java |grep -v grep |awk '{print $2}') 这个变量名与我们的`java_bin`冲突,我们不需要修改,因为它们是不同的变量。 但是,为了避免混淆,我们可以将`java_bin`变量名改为`JAVA_BIN`(大写),以区别于其他变量。 修改后的完整脚本较长,这里不全部展示,但关键修改已经说明。 最后,我们还需要注意:在通过SSH执行时,脚本中的`source`命令可能因为权限问题而失败(例如,用户目录下的配置文件不可读),因此需要确保这些文件可读。 总结修改: 1. 在开头加载环境配置文件,确保PATH设置正确。 2. 使用`which java`获取Java路径,并检查是否存在。 3. 将启动Java的命令改为使用`$JAVA_BIN`(或`$java_bin`)变量。 这样修改后,脚本在SSH执行时应该能正确找到Java环境。 注意:由于脚本较长,修改时请仔细检查替换。 由于无法直接运行测试,请根据实际情况调整。 如果问题仍然存在,可以在脚本中临时输出环境变量和PATH,用于调试: echo "PATH: $PATH" echo "JAVA_BIN: $JAVA_BIN" 这样可以帮助定位问题。 修改后的部分代码示例(仅开头和启动部分): ```bash #!/bin/bash #source ~/.bashrc source /etc/profile # 加载用户环境文件 [ -f ~/.bash_profile ] && source ~/.bash_profile >/dev/null 2>&1 [ -f ~/.bash_login ] && source ~/.bash_login >/dev/null 2>&1 [ -f ~/.profile ] && source ~/.profile >/dev/null 2>&1 [ -f ~/.bashrc ] && source ~/.bashrc >/dev/null 2>&1 # 获取Java可执行文件路径 JAVA_BIN=$(which java) if [ -z "$JAVA_BIN" ]; then echo "Error: java not found. Please ensure Java Runtime Environment (JRE) is installed and in the PATH." exit 1 fi # 其他原有代码... ``` 在启动jar包的地方,例如: nohup $JAVA_BIN -Dfile.encoding=utf-8 -Xms256M -Xmx256M -jar ... 替换所有类似的地方。 由于原脚本非常长,这里无法一一替换,但思路已经明确。 另外,原脚本中还有一处: java_path=$(dirname $(dirname $(readlink -f $(which javac)))) 我们不再需要,可以删除,因为我们使用`JAVA_BIN`。 但是,注意原脚本后面有使用`java_path`的地方,我们已经替换为`JAVA_BIN`,所以这个变量可以删除了。 所以,删除`export java_path=...`这一行。 最后,请根据实际情况测试调整。</think>要让脚本在通过SSH执行时正确获取Java环境,需要解决环境变量加载和路径识别问题。以下是关键修改方案: ### 1. 环境变量加载问题 SSH执行时默认加载的环境与交互式shell不同,需要显式加载环境文件: ```bash #!/bin/bash # 显式加载系统和个人环境文件 source /etc/profile [ -f ~/.bash_profile ] && source ~/.bash_profile [ -f ~/.bashrc ] && source ~/.bashrc ``` ### 2. Java路径识别优化 使用更可靠的Java路径获取方式: ```bash # 方法1:优先使用JAVA_HOME(如果已设置) if [ -n "$JAVA_HOME" ]; then java_bin="$JAVA_HOME/bin/java" # 方法2:使用which查找java路径 elif which java &>/dev/null; then java_bin=$(which java) # 方法3:尝试常见安装路径 else possible_paths=( "/usr/bin/java" "/usr/local/bin/java" "/opt/jdk*/bin/java" "/usr/lib/jvm/*/bin/java" ) for path in "${possible_paths[@]}"; do if [ -x "$path" ]; then java_bin="$path" break fi done fi # 验证Java是否找到 if [ -z "$java_bin" ]; then echo "ERROR: Java not found! Please install JDK." exit 1 fi ``` ### 3. 完整修改示例 以下是修改后的关键部分: ```bash #!/bin/bash # 显式加载环境配置 source /etc/profile [ -f ~/.bash_profile ] && source ~/.bash_profile [ -f ~/.bashrc ] && source ~/.bashrc # 可靠的Java路径获取 find_java() { # 1. 检查JAVA_HOME if [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ]; then echo "$JAVA_HOME/bin/java" return fi # 2. 检查PATH中的java type -p java &>/dev/null && echo java && return # 3. 扫描常见安装路径 local paths=( /usr/bin/java /usr/local/bin/java /opt/jdk*/bin/java /usr/lib/jvm/*/bin/java ) for path in "${paths[@]}"; do if [ -x "$path" ]; then echo "$path" return fi done # 未找到 echo "JAVA_NOT_FOUND" } java_bin=$(find_java) if [ "$java_bin" = "JAVA_NOT_FOUND" ]; then echo "ERROR: Java not found! Tried:" echo "1. JAVA_HOME: $JAVA_HOME" echo "2. System PATH" echo "3. Common install locations" exit 1 fi # 后续脚本中使用$java_bin代替原$java_path/bin/java # 示例修改启动命令: nohup "$java_bin" -Dfile.encoding=utf-8 -Xms256M -Xmx256M -jar "$jar_file" > "$log_file" 2>&1 & ``` ### 4. 其他优化建议 1. **移除不必要的导出**: ```bash # 移除这些全局导出 unset JAR_NAMES JAR_PID di1lie di2lie ``` 2. **路径引号处理**: ```bash # 所有路径变量使用双引号包裹 nohup "$java_bin" -jar "${FILE_NAME[i]}" > "${FILE_NAME[i]}.log" 2>&1 & ``` 3. **SSH执行测试命令**: ```bash ssh user@host 'source /etc/profile; source ~/.bashrc; /path/to/script.sh startall' ``` ### 修改后脚本优势 1. **三层Java查找机制**:优先使用JAVA_HOME,其次PATH查找,最后扫描常见路径 2. **环境隔离处理**:显式加载所有可能的环境配置文件 3. **错误处理**:明确的Java检测失败提示 4. **路径安全**:所有路径使用引号包裹,防止空格导致的错误 这些修改确保脚本在SSH、cron等非交互式环境中能可靠获取Java环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值