I have a bash script, /usr/bin/local/myscript. I run the file usually from an external software (in my case Autohotkey), basically I mean the script will be finished immediately and the window closes so I cannot see any logs on the window, info logs or error logs. So I do like to "script" the entire running steps for debugging when the program didn't work well. But simply putting a script ~/script.txt in the first of the myscript file didn't work, I don't know what is going on, the next lines on the file didn't executed basically. So, is there a (proper) way to use "script" in bash files, or better alternative to "script" for this?


But simply putting a script ~/script.txt in the first of the myscript file didn't work, I don't know what is going on, the next lines on the file didn't executed basically.

For a shell interpreting myscript, script ~/script.txt is just a command that runs an external executable. The executable is script in this case.

If the executable was sleep, tar or ls, you would expect the shell to wait till the executable finishes before interpreting the rest of myscript. With script it's not different: the shell waits for script to finish.

script is intended for interactive use. script ~/script.txt runs an interactive shell which is not the shell that interprets myscript. You wrote "the window closes" (when without script), so I assume myscript runs in some terminal emulator that displays a window. If so, then (with script) you probably saw this inner shell started by script and could interact with it while the outer shell was waiting. script logs what you do in the inner shell. Exiting the inner shell terminates script and only then the outer shell (i.e. myscript) continues. But maybe you closed the terminal emulator, the outer shell got SIGHUP and never continued.

This is not important since it should now be clear script called from within myscript cannot help you with debugging myscript, even if the outer shell continues.

There are at least two methods to debug myscript:

  1. Redirect stderr of the script to a logfile. This can be done from within the script with

    # just after shebang
    exec 2>/path/to/logfile

    If myscript generates output on its stdout that is important and actually goes somewhere (via a pipe or redirection) then you don't want to break this. But if it normally prints to the terminal and you'd like to log this as well then redirect both stderr and stdout to the logfile:

    # just after shebang
    exec 2>/path/to/logfile 1>&2

    This method will work even if myscript runs without a terminal.

  2. Alternatively let the script run an interactive shell (e.g. bash) at the very end. The new shell will prevent the window from closing and you will be able to see what the script has printed to the terminal so far. This obviously requires a terminal. Note if myscript happens to exit or kill itself or exec to another executable then it will never get to the line with bash; take it into consideration.

    If for some reason the interactive bash started from the script clears the terminal or something, use sleep 3600 instead. The point is you don't really need an extra shell, you need any process that keeps the terminal emulator open long enough so you can examine the previous output.

No matter which method you choose, place

set -x

early in myscript to make the shell interpreting it print commands and they arguments as they are executed. This should give you useful insight.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.