java窗口程序不能通过双击shell脚本执行?

sh/bash/dash/ksh/zsh等Shell脚本
回复
头像
两瓶啤酒
帖子: 41
注册时间: 2019-05-16 10:10
系统: ubuntu 20.04

java窗口程序不能通过双击shell脚本执行?

#1

帖子 两瓶啤酒 » 2020-09-24 15:20

一个java窗口程序,可以在命令行通过"java -jar Test.jar"执行,但将"java -jar Test.jar"写入test.sh给执行权限,却不能通过双击test.sh打开窗口。什么原因?
头像
两瓶啤酒
帖子: 41
注册时间: 2019-05-16 10:10
系统: ubuntu 20.04

Re: java窗口程序不能通过双击shell脚本执行?

#2

帖子 两瓶啤酒 » 2020-09-24 16:25

知道如何解决了,需要在脚本中指定java的绝对路径。看来双击执行脚本,并没有继承系统的环境变量。
头像
astolia
论坛版主
帖子: 6450
注册时间: 2008-09-18 13:11

Re: java窗口程序不能通过双击shell脚本执行?

#3

帖子 astolia » 2020-09-25 10:31

是Test.jar的路径没有指定吧。在脚本里加一句env > /tmp/env.txt,看里面的环境变量是什么
头像
两瓶啤酒
帖子: 41
注册时间: 2019-05-16 10:10
系统: ubuntu 20.04

Re: java窗口程序不能通过双击shell脚本执行?

#4

帖子 两瓶啤酒 » 2020-09-25 14:30

astolia 写了: 2020-09-25 10:31 是Test.jar的路径没有指定吧。在脚本里加一句env > /tmp/env.txt,看里面的环境变量是什么
jar文件倒是指定路径了。print出来的env 变量,$PATH缺少/opt/jdk18/bin,而/opt/jdk18/bin我是在~/.bashrc中加入的。在~/.bashrc注释中说,~/.bashrc: executed by bash(1) for non-login shells.那就是说,双击执行的shell脚本,没有执行~/.bashrc。
头像
两瓶啤酒
帖子: 41
注册时间: 2019-05-16 10:10
系统: ubuntu 20.04

Re: java窗口程序不能通过双击shell脚本执行?

#5

帖子 两瓶啤酒 » 2020-09-25 15:41

哈,linux由unix而来,unix是设计用于多用户&字符界面的系统,每个用户登陆后,有自己的shell包含自己的环境变量,所执行的脚本也是继承了自己的环境变量。

现在的linux,却基本用图形界面,一个shell双击执行它,没有用户的环境变量可继承,怪不得一般的java UI软件都需要安装呢,必须在安装的时候获取java的路径。
头像
astolia
论坛版主
帖子: 6450
注册时间: 2008-09-18 13:11

Re: java窗口程序不能通过双击shell脚本执行?

#6

帖子 astolia » 2020-09-26 12:18

两瓶啤酒 写了: 2020-09-25 14:30 jar文件倒是指定路径了。print出来的env 变量,$PATH缺少/opt/jdk18/bin,而/opt/jdk18/bin我是在~/.bashrc中加入的。在~/.bashrc注释中说,~/.bashrc: executed by bash(1) for non-login shells.那就是说,双击执行的shell脚本,没有执行~/.bashrc。
两瓶啤酒 写了: 2020-09-25 15:41 现在的linux,却基本用图形界面,一个shell双击执行它,没有用户的环境变量可继承
可以看得出来,你并不十分清楚shell脚本的执行机制,也没有真正理解那段注释的内容,还对“用户的环境变量”这个概念有误解。

先说双击执行的事。如果你的脚本开头中没有写shebang(shebang就是#!interpreter这种东西),系统会用/bin/sh来执行,否则用shebang中指定的interpreter来执行,脚本文件作为/bin/sh或interpreter的第一个参数。而/bin/sh只要求是一个posix兼容的shell,并不要求一定是bash。在现在的ubuntu上,/bin/sh是一个指向dash的符号链接。
这里是第一个坑,如果你没有写shebang或者写的是#!/bin/sh,那么用的是dash来执行,.bashrc这个属于bash的配置文件,dash是不会去管的。

再来是.bashrc的作用。你最好还是去看bash的manpage https://manpages.ubuntu.com/manpages/fo ... ash.1.html 在INVOCATION一节中,详细说明了什么情况下会去处理.bashrc的内容,我在这里就不赘述了。
你读过了就知道,即使你的shebang写的是#!/bin/bash或者把/bin/sh改成了指向bash,通过双击执行这种行为来调用bash去执行你的脚本,默认也不会去管.bashrc的内容。

普通情况下,一个进程的环境变量是从它的父进程继承而来,所以你双击执行的时候,环境变量是从提供图形界面的程序继承而来的,这个程序不是bash,自然不会去管.bashrc。你该去改那个图形界面的程序会去使用的配置文件,比如~/.profile、/etc/environment之类的
两瓶啤酒 写了: 2020-09-25 15:41 怪不得一般的java UI软件都需要安装呢,必须在安装的时候获取java的路径。
在安装时获取java的路径这一行为,主要是方便处理不同jdk/jre的安装路径。不同linux发行版自带的jdk/jre安装路径都不一定一样,还有多个不同版本共存的情况,更不用说像你那样把jdk安装到了其他的位置。
头像
两瓶啤酒
帖子: 41
注册时间: 2019-05-16 10:10
系统: ubuntu 20.04

Re: java窗口程序不能通过双击shell脚本执行?

#7

帖子 两瓶啤酒 » 2020-09-28 11:09

astolia 写了: 2020-09-26 12:18
两瓶啤酒 写了: 2020-09-25 14:30 jar文件倒是指定路径了。print出来的env 变量,$PATH缺少/opt/jdk18/bin,而/opt/jdk18/bin我是在~/.bashrc中加入的。在~/.bashrc注释中说,~/.bashrc: executed by bash(1) for non-login shells.那就是说,双击执行的shell脚本,没有执行~/.bashrc。
两瓶啤酒 写了: 2020-09-25 15:41 现在的linux,却基本用图形界面,一个shell双击执行它,没有用户的环境变量可继承
可以看得出来,你并不十分清楚shell脚本的执行机制,也没有真正理解那段注释的内容,还对“用户的环境变量”这个概念有误解。

先说双击执行的事。如果你的脚本开头中没有写shebang(shebang就是#!interpreter这种东西),系统会用/bin/sh来执行,否则用shebang中指定的interpreter来执行,脚本文件作为/bin/sh或interpreter的第一个参数。而/bin/sh只要求是一个posix兼容的shell,并不要求一定是bash。在现在的ubuntu上,/bin/sh是一个指向dash的符号链接。
这里是第一个坑,如果你没有写shebang或者写的是#!/bin/sh,那么用的是dash来执行,.bashrc这个属于bash的配置文件,dash是不会去管的。

再来是.bashrc的作用。你最好还是去看bash的manpage https://manpages.ubuntu.com/manpages/fo ... ash.1.html 在INVOCATION一节中,详细说明了什么情况下会去处理.bashrc的内容,我在这里就不赘述了。
你读过了就知道,即使你的shebang写的是#!/bin/bash或者把/bin/sh改成了指向bash,通过双击执行这种行为来调用bash去执行你的脚本,默认也不会去管.bashrc的内容。

普通情况下,一个进程的环境变量是从它的父进程继承而来,所以你双击执行的时候,环境变量是从提供图形界面的程序继承而来的,这个程序不是bash,自然不会去管.bashrc。你该去改那个图形界面的程序会去使用的配置文件,比如~/.profile、/etc/environment之类的
我当然明白shebang的作用,但我这里的脚本只有一句"java -jar xxxx.jar",实际我也试了,有没有shebang并没有区别。我上面那一段写的是不够精确,只是便于理解的一种说法。我以前确实没有注意shell分交互式/非交互式以及登陆非登陆的区别,这几种不同的方式,继承的环境变量是不同的。bash那个注释说的是对于non-login shells,但没有提交互式/非交互式,双击脚本显然是非交互式,事实也证明双击脚本没有执行~/.bashrc。我看到的资料没有明确提到双击执行脚本这个行为,我会去看看你给的文档。
头像
lilydjwg
论坛版主
帖子: 4249
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: java窗口程序不能通过双击shell脚本执行?

#8

帖子 lilydjwg » 2020-10-11 17:10

两瓶啤酒 写了: 2020-09-25 14:30
jar文件倒是指定路径了。print出来的env 变量,$PATH缺少/opt/jdk18/bin,而/opt/jdk18/bin我是在~/.bashrc中加入的。在~/.bashrc注释中说,~/.bashrc: executed by bash(1) for non-login shells.那就是说,双击执行的shell脚本,没有执行~/.bashrc。
所以全局性变量不要加在 ~/.bashrc 里。系统级的都是往 /etc/profile.d 下写,用户级的可以写在 ~/.profile。一般的图形界面登录器会读取这些文件的,bashrc 肯定是不读的。

bash 脚本执行的时候也是不读取 bashrc 的,因为 bashrc 是给交互时执行的。参考 https://blog.flowblok.id.au/2013-02/she ... ripts.html (有图)
回复