termux / termux-widget

Termux add-on app which adds shortcuts to commands on the home screen.
https://f-droid.org/en/packages/com.termux.widget
Other
1k stars 117 forks source link

profile and rc scripts are ignored by interpreter #114

Closed YanceyChiew closed 6 months ago

YanceyChiew commented 6 months ago

Problem description

Using the shortcuts in the widget to start the script will not execute the rc script of the script interpreter, such as ~/.bashrc, ~/.zshrc, nor the ~/.profile (.bash_login|.bash_profile) of the login shell.

After specifying the interpreter as /bin/bash in the shebang, executing echo $SHELL displays $PREFIX/bin/login (PREFIX=/data/data/com.termux/files/usr), which internally sources another script $PREFIX/etc/termux-login.sh.

All the above files, as well as $PREFIX/etc/profile and $PREFIX/etc/bash.bashrc, the environment variables exported, the instructions info printed by echo, and the marks written to the files are not effective. It can be judged that none of them have been executed.

Steps to reproduce

  1. Create a script in the ~/.shortcuts directory. Let’s see, call it test.sh, and give it executable permissions.
  2. Write a few lines like this:
    #!/bin/bash
    echo $0
    env
    echo $SHELL
    bash
  3. Export the environment variables used for identification in all the profile and rc scripts mentioned above, such as export ETC_PROFILE=LOADED in $PREFIX/etc/profile.
  4. Run test.sh from the desktop widget and view the output, none of the environment variables used for the identification were successfully set.
  5. Execute the env command in the interactive bash started by the test.sh script, and all environment variables are output correctly.

Expected behavior

The contents in ~/.profile (or ~/.bash_login|~/.bash_profile if exist) and ~/.bashrc should be executed, so the env in test.sh should output relevant environment variables.

Additional information

The results are the same under zsh/fish/sh.

agnostic-apollo commented 6 months ago

A shell script is a text file containing shell commands. When such a file is used as the first non-option argument when invoking Bash, and neither the -c nor -s option is supplied (see Invoking Bash), Bash reads and executes commands from the file, then exits. This mode of operation creates a non-interactive shell.

Invoked non-interactively When Bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute.

Interactive and login shell rc files are not sourced when shell scripts are executed, that is standard behaviour. Either manually source files, or pass --login argument in shebang (that should work).

YanceyChiew commented 6 months ago

Interactive and login shell rc files are not sourced when shell scripts are executed, that is standard behaviour. Either manually source files, or pass --login argument in shebang (that should work).

That makes sense. When I see the value $PREFIX/bin/login in $SHELL, although I don't know where it comes from and I have tested that it is not executed, I still assume that termux:widget starts a login shell. This is a mistake. I should confirm the output of shopt first.

But even if the --login parameter is added to the shebang, termux:widget still starts a non-login shell. I have started the script through the gnome-shell shortcut key under Debian, and confirmed in the log that the expected behavior is met.

YanceyChiew commented 6 months ago

The main point of this issue is that the environment variables cannot be set in advance for the shell started by termux:widget.

In an already opened login shell, or in the Linux desktop, running scripts in a non-interactive non-login shell can inherit the environment variables of their parent process, and some of these environment variables come from sourcing the profile.

Termux:widget lacks such a way, so that the BASH_ENV mentioned above also has nowhere to set, and the script can only be modified to adapt to such an execution environment.

agnostic-apollo commented 6 months ago

But even if the --login parameter is added to the shebang, termux:widget still starts a non-login shell.

Termux app would start the script itself by manually passing it to the interpreter, and arguments are currently ignored. It should work for sub scripts though or could try running script with tudo -s.

Termux:widget lacks such a way

Yeah, termux app forks from the main app process and only android specific variables are set. However, additional env variables support will be available in next version as it was already implemented during termux-widget rewrite, no timeline currently for release date.