Java如何获取主机HostIP进程Pid

获取本地Ip和HostName

 import java.net.InetAddress;
    public class GetIPANDHostName {


        public static void main(String[] args) throws Exception {
            InetAddress addr = InetAddress.getLocalHost();
            String ip = addr.getHostAddress().toString(); //获取本机ip
            String hostName = addr.getHostName().toString(); //获取本机计算机名称
            System.out.println(ip);
            System.out.println(hostName);
        }
    }

获取本地的进程PID

public class GetPID {
    private static String getPid()
    {
        /*
         * runtimeMXBean.getName()取得的值包括两个部分:PID和hostname,两者用@连接。
         */
        RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        return runtimeMXBean.getName().split("@")[0];
    }

    public static void main(String[] args) {
        System.out.println("pid为:"+getPid());
    }
}

 

<think>为了使用paramiko在远程服务器上执行`nohup java -jar`命令,我们需要考虑以下几个步骤: 1. 使用paramiko建立SSH连接。 2. 在远程服务器上查找Java的安装路径(如果环境变量未设置,可能需要通过其他方式查找)。 3. 使用找到的Java路径执行`nohup`命令来运行指定的jar包。 4. 处理执行过程中的输入输出,特别是nohup会忽略输入并将输出重定向到文件。 由于不同的服务器环境可能不同,我们假设Java可能安装在常见路径(如/usr/bin/java, /usr/local/bin/java)或者我们可以通过`which java`或`command -v java`来获取路径。但是,如果通过SSH执行命令,环境变量可能不会像交互式shell那样加载,因此我们可能需要指定绝对路径或者先加载环境变量。 这里我们选择使用`which java`来获取Java的路径,因为这样比较简单。但是要注意,`which`命令在某些系统上可能不可用,或者Java可能不在PATH中。因此,我们可能需要考虑备选方案。 步骤: 1. 连接SSH。 2. 执行`which java`命令获取Java路径。如果失败,尝试使用`readlink -f $(which java)`获取真实路径(因为可能是符号链接),或者尝试其他已知路径。 3. 使用获取到的Java路径,执行`nohup <java_path> -jar your_jar.jar &`,同时将输出重定向到文件(如nohup.out)。 但是,由于我们使用paramiko执行命令时,当SSH会话关闭时,我们执行的命令可能会被终止,除非我们使用nohup并且重定向输入输出。另外,paramiko的`exec_command`在命令执行完成前会一直阻塞,而nohup命令会立即返回(因为它在后台运行),所以我们需要确保命令在后台运行并让paramiko能够返回。 此外,我们还需要注意,nohup会忽略SIGHUP信号,并且会重定向标准输入、标准输出和标准错误。通常,我们会将输出重定向到文件,例如:`nohup java -jar app.jar > nohup.out 2>&1 &`。 但是,如果我们使用paramiko执行这个命令,由于命令中有重定向和后台运行符号`&`,我们需要确保整个命令被正确解析。我们可以将整个命令作为一个字符串传递给`exec_command`。 另外,如果我们想要在命令执行后立即退出paramiko而不等待命令结束,那么使用`&`将命令放入后台即可。 计划: 1. 通过SSH执行`which java`,获取Java路径。如果失败,则尝试使用`/usr/bin/java`等默认路径,或者抛出异常。 2. 构建nohup命令:`nohup <java_path> -jar <jar_path> > <log_file> 2>&1 &` 3. 执行这个命令,并检查执行结果(通过返回状态码)。 注意:由于nohup命令会立即返回(因为它在后台运行),所以我们可以通过检查命令的退出状态来初步判断命令是否成功启动(但注意,这只能判断nohup命令本身是否成功,不能判断java程序是否成功启动)。 代码示例: ```python import paramiko import time # 设置SSH连接参数 hostname = 'your_host' port = 22 # 默认SSH端口 username = 'your_username' password = 'your_password' # 或者使用密钥认证 jar_path = '/path/to/your_jar.jar' # 远程服务器上的jar包路径 log_file = '/path/to/nohup.out' # 日志文件路径 # 创建SSH客户端 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: # 连接服务器 ssh.connect(hostname, port, username, password) # 第一步:获取Java路径 stdin, stdout, stderr = ssh.exec_command('which java') java_path = stdout.read().decode().strip() # 如果获取不到,尝试使用其他方法或默认路径 if not java_path: # 尝试使用其他方法,例如:尝试查找/usr/bin/java # 或者使用命令:command -v java stdin, stdout, stderr = ssh.exec_command('command -v java') java_path = stdout.read().decode().strip() if not java_path: # 尝试使用默认路径 java_path = '/usr/bin/java' # 或者抛出异常 # raise Exception("Java not found") # 第二步:构建并执行nohup命令 # 注意:这里我们假设jar_path和log_file都是绝对路径 command = f"nohup {java_path} -jar {jar_path} > {log_file} 2>&1 &" # 执行命令 stdin, stdout, stderr = ssh.exec_command(command) # 获取返回码,注意:由于命令在后台运行,执行命令会立即返回,所以返回码可能为0(表示nohup命令启动成功) exit_status = stdout.channel.recv_exit_status() if exit_status != 0: # 读取错误信息 error = stderr.read().decode() print(f"Error starting jar: {error}") else: print("Command started successfully.") except Exception as e: print(f"An error occurred: {str(e)}") finally: # 关闭连接 ssh.close() ``` 注意:上述代码中,我们使用了两次`exec_command`,这可能会因为环境变量问题导致第二次命令执行时找不到Java。因为每次`exec_command`都是在一个新的shell中执行,而环境变量可能不会继承。所以,如果第一次执行`which java`成功,但第二次执行nohup命令时,可能由于环境变量不同导致java_path不可用。为了避免这种情况,我们可以使用绝对路径。 另外,如果服务器上配置了多个Java版本,我们可能需要加载特定的环境变量(如通过source ~/.bashrc等),但是`exec_command`启动的是非交互式shell,不会加载用户的环境配置文件。因此,我们可以尝试在命令中加载环境变量,或者使用绝对路径。 另一种方法:我们可以将获取Java路径和启动命令放在同一个命令中,例如: ```bash source ~/.bashrc && nohup $(which java) -jar your_jar.jar > nohup.out 2>&1 & ``` 但是,如果`which java`在非交互式shell中不可用,那么这种方法可能失败。 因此,更可靠的方法是使用绝对路径,或者如果知道Java安装路径,直接使用。 改进:我们可以先尝试获取Java路径,如果获取到的是符号链接,则使用`readlink -f`解析真实路径。然后使用真实路径执行。 另外,我们也可以考虑使用`java`命令直接启动,因为如果环境变量PATH在非交互式shell中设置正确,那么直接使用`java`可能也是可以的。但是,为了避免环境变量问题,我们最好使用绝对路径。 所以,我们可以修改为: ```python # 在获取java_path后,解析真实路径(如果是符号链接) if java_path: # 如果找到了java_path stdin, stdout, stderr = ssh.exec_command(f'readlink -f {java_path}') real_java_path = stdout.read().decode().strip() if real_java_path: java_path = real_java_path # 否则,使用原来的java_path ``` 然后使用`java_path`作为绝对路径。 最后,关于nohup命令的执行,我们还可以考虑使用`screen`或`tmux`来运行程序,这样更便于管理。但是,这里我们按照要求使用nohup。 另外,我们也可以使用paramiko的invoke_shell来执行命令,这样可以模拟一个交互式shell,从而加载环境变量。但是,这样会复杂一些。如果环境变量问题导致无法找到Java,那么使用绝对路径是最稳妥的。 总结:上面的代码示例已经展示了基本步骤。在实际使用中,可能需要根据具体环境调整。 最后,我们输出一些相关信息,比如命令执行后的输出和错误,以及退出状态。 注意:nohup命令启动后,程序在后台运行,paramiko执行完命令后就可以断开连接,不会影响程序的运行。 相关问题: 1. 如何通过paramiko在远程服务器上执行需要交互的命令? 2. 使用paramiko时,如何保持长时间运行的命令在断开SSH连接后继续执行? 3. 如何使用paramiko上传文件(如jar包)到远程服务器? 4. 除了nohup,还有哪些方法可以在断开SSH连接后保持程序运行?</think>### 使用 Paramiko 执行 `nohup java -jar` 的完整方案 以下是使用 Paramiko 在远程服务器上自动获取 Java 路径并执行 `nohup java -jar` 的 Python 实现: ```python import paramiko import re def run_java_jar(host, port, username, password, jar_path, java_path_hint=None): """ 在远程服务器上执行 nohup java -jar 命令 参数: host: 远程服务器IP port: SSH端口 username: SSH用户名 password: SSH密码 jar_path: 远程服务器上的JAR文件路径 java_path_hint: (可选) Java路径提示,用于搜索优先级 """ client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: # 连接到服务器 client.connect(host, port, username, password) # 1. 自动查找Java路径 java_path = find_java_path(client, java_path_hint) print(f"✅ 找到Java路径: {java_path}") # 2. 构建并执行命令 command = build_nohup_command(java_path, jar_path) print(f"🚀 执行命令: {command}") # 3. 在后台执行命令 stdin, stdout, stderr = client.exec_command(command) # 4. 检查命令是否成功启动 exit_status = stdout.channel.recv_exit_status() if exit_status != 0: error = stderr.read().decode().strip() raise RuntimeError(f"❌ 命令执行失败 (状态码 {exit_status}): {error}") print("🎉 应用已在后台成功启动") return True except Exception as e: print(f"⚠️ 发生错误: {str(e)}") return False finally: client.close() def find_java_path(client, hint=None): """自动查找Java安装路径""" search_paths = [ hint, # 用户提供的提示路径 "/usr/bin/java", "/usr/local/bin/java", "/opt/java/bin/java", "/usr/lib/jvm/java-11-openjdk-amd64/bin/java", # 常见OpenJDK路径 "/usr/lib/jvm/java-8-openjdk-amd64/bin/java" ] # 尝试所有可能的路径 for path in filter(None, set(search_paths)): stdin, stdout, stderr = client.exec_command(f"test -x {path} && echo exists") if stdout.read().decode().strip() == "exists": return path # 尝试通过which查找 stdin, stdout, stderr = client.exec_command("which java || command -v java") which_path = stdout.read().decode().strip() if which_path and "not found" not in which_path: return which_path # 尝试通过update-alternatives查找 stdin, stdout, stderr = client.exec_command( "update-alternatives --list java 2>/dev/null | head -1" ) alt_path = stdout.read().decode().strip() if alt_path: return alt_path raise FileNotFoundError("❌ 无法找到Java路径,请手动指定") def build_nohup_command(java_path, jar_path): """构建nohup命令""" return ( f"nohup {java_path} -jar {jar_path} > /dev/null 2>&1 & " "echo $! > .app.pid && sleep 1" ) # 使用示例 if __name__ == "__main__": run_java_jar( host="192.168.1.100", port=22, username="deploy", password="your_password", jar_path="/opt/myapp/app.jar", java_path_hint="/usr/lib/jvm/jdk-17/bin/java" # 可选提示 ) ``` ### 代码解释 1. **SSH 连接管理**: - 使用 `paramiko.SSHClient` 建立 SSH 连接 - `AutoAddPolicy` 自动接受未知主机密钥 2. **Java 路径查找逻辑**: - 优先尝试用户提供的提示路径 - 检查常见安装路径 (`/usr/bin/java`, `/usr/local/bin/java` 等) - 使用 `which` 或 `command -v` 命令查找 - 通过 `update-alternatives` 获取系统默认 Java 3. **命令构建**: - `nohup` 忽略挂断信号 - `> /dev/null 2>&1` 重定向所有输出 - `&` 在后台运行 - `echo $! > .app.pid` 保存进程 ID - `sleep 1` 确保进程启动 4. **错误处理**: - 检查命令退出状态码 - 捕获并显示标准错误输出 - 确保连接始终关闭 ### 最佳实践建议 1. **使用密钥认证**: ```python # 替换密码认证为密钥认证 client.connect(host, port, username, key_filename="/path/to/private_key") ``` 2. **添加进程管理**: ```python # 检查进程是否运行 def check_process(client): stdin, stdout, stderr = client.exec_command("ps -p $(cat .app.pid) >/dev/null && echo running") return "running" in stdout.read().decode() ``` 3. **日志重定向改进**: ```python # 将日志输出到文件 command = f"nohup {java_path} -jar {jar_path} > app.log 2>&1 &" ``` 4. **环境变量支持**: ```python # 添加JVM参数 command = f"nohup {java_path} -Xmx2G -Dspring.profiles.active=prod -jar {jar_path} ..." ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值