How can I print each command before executing? [duplicate]
What is the best way to set up a Bash script that prints each command before it executes it? That would be great for debugging purposes. I already tried this:
CMD="./my-command --params >stdout.txt 2>stderr.txt" echo $CMD `$CMD`
./my-command --params >stdout.txt 2>stderr.txt
I think you would have better luck if you changed `$CMD` to «$CMD» . When bash encounters `$CMD` , it replaces $CMD with the command and you’re left with `./my-command —params >stdout.txt 2>stderr.txt` . Since this is wrapped in backticks, bash will execute the command, and instead of printing the output to stdout, it will replace the expression including the backticks with the output of the command, and since this ends up in the beginning of a command line, bash will try to interpret the output as a new command, which is not what you want.
@HelloGoodbye In fact, don’t even use the quotes. With quotes, bash tries to interpret the entire string as the name of the command; without quotes bash expands it properly and treats it as a command followed by args, redirects, etc., exactly as it would usually interpret it if you typed it in directly
Relevant, in particular setting of the PS4 variable in order to define the prompt displayed as prefix of commands in tracing output: thegeekstuff.com/2008/09/…
@KenBellows, that’s untrue. Unquoted expansion is not the same as evaluation as code: Quotes aren’t honored, redirections aren’t honored — all that syntax is treated as literals. The only parsing steps that happen are string splitting and glob expansion. This is the core topic of BashFAQ #50. If you want quotes/redirects/etc to be honored it would be eval «$CMD» , but that itself has serious security risks, which is why FAQ #50 doesn’t suggest eval but instead teaches use of arrays and functions.
How to get list of commands used in a shell script?
I have a shell script of more than 1000 lines, i would like to check if all the commands used in the script are installed in my Linux operating system. Is there any tool to get the list of Linux commands used in the shell script? Or how can i write a small script which can do this for me? The script runs successfully on the Ubuntu machine, it is invoked as a part of C++ application. we need to run the same on a device where a Linux with limited capability runs. I have identified manually, few commands which the script runs and not present on Device OS. before we try installing these commands i would like to check all other commands and install all at once. Thanks in advance
Arek Thanks, it helps little bit but not exactly what i was looking for. I need to know what all commands the script uses. i can not run the entire script at one shot as it runs part by part based on the arguments. as of now we do not have all the information about arguments.
1000 lines isn’t that long, and most of it is probably either shell-specific (like if , while , etc) or repetitive (the same command being called repeatedly with different arguments.) You’ll probably spend less time scanning it manually than you will looking for a way to do it automatically.
Your best bet: update your script to wrap command execution with your own function, then in this function log the command and just pass through to the command itself. run() < echo "$1" >/tmp/commands; $@; > or such.
4 Answers 4
I already tried this in the past and got to the conclusion that is very difficult to provide a solution which would work for all scripts. The reason is that each script with complex commands has a different approach in using the shells features. In case of a simple linear script, it might be as easy as using debug mode. For example: bash -x script.sh 2>&1 | grep ^+ | awk » | sort -u In case the script has some decisions, then you might use the same approach an consider that for the «else» cases the commands would still be the same just with different arguments or would be something trivial (echo + exit).
In case of a complex script, I attempted to write a script that would just look for commands in the same place I would do it myself. The challenge is to create expressions that would help identify all used possibilities, I would say this is doable for about 80-90% of the script and the output should only be used as reference since it will contain invalid data (~20%).
Here is an example script that would parse itself using a very simple approach (separate commands on different lines, 1st word will be the command):
# 1. Eliminate all quoted text # 2. Eliminate all comments # 3. Replace all delimiters between commands with new lines ( ; | && || ) # 4. extract the command from 1st column and print it once cat $0 \ | sed -e 's/\"/./g' -e "s/'[^']*'//g" -e 's/"[^"]*"//g' \ | sed -e "s/^[[:space:]]*#.*$//" -e "s/\([^\\]\)#[^\"']*$/\1/" \ | sed -e "s/&&/;/g" -e "s/||/;/g" | tr ";|" "\n\n" \ | awk '' | sort -u
There are many more cases to consider (command substitutions, aliases etc.), 1, 2 and 3 are just beginning, but they would still cover 80% of most complex scripts. The regular expressions used would need to be adjusted or extended to increase precision and special cases.
In conclusion if you really need something like this, then you can write a script as above, but don’t trust the output until you verify it yourself.
how to print out all commands in bash script [duplicate]
I know «set -x» will print out commands in current script. but if the script a.sh runs b.sh then b.sh won’t print out commands. is there a way set -x globally so all commands print out?
x@ASUS:~$ cat a.sh #!/bin/bash set -x echo "a.sh" ./b.sh x@ASUS:~$ cat b.sh #!/bin/bash echo "b.sh" x@ASUS:~$ ./a.sh
2 Answers 2
Yes, you need to source the second script instead of executing it.
Executing it will spawn a new shell, which is not affected by set -x . Sourcing it will instead execute the script in the current shell, where you’ve run set -x .
[1:24 anon] ~$ cat ./a.sh #!/bin/bash set -x echo "a.sh" source ./b.sh [1:26 anon] ~$ cat ./b.sh #!/bin/bash echo "b.sh" [1:26 anon] ~$ ./a.sh + echo a.sh a.sh + source ./b.sh ++ echo b.sh b.sh
Note that sourcing scripts that aren’t designed for it can lead to confusing behaviour if the sourced script alters global state. eg: n=1; . ./b.sh; echo «$n» could echo an unexpected value if b.sh sets its own n variable
As long as b.sh does not call set +x , then you can do:
This should survive intermediate non-bash subprocesses that don’t sanitise their environment, but only works with bash scripts (eg. scripts with #!/bin/sh bang-path won’t display traces).
bash$ cat a2.sh #!/bin/bash export SHELLOPTS set -x echo "a2.sh" awk 'BEGIN' ./b.sh EOD bash$ chmod +x a2.sh bash$ ./a2.sh + echo a2.sh a2.sh + awk 'BEGIN' a1 + echo a2 a2 + echo b.sh b.sh + ./b.sh + echo b.sh b.sh bash$
How to get a list of all the commands available for Ubuntu?
I want to start using the terminal more often, but I don’t know what are the different commands available to me. Is there a way to list all the different commands that I can make use of?
7 Answers 7
First Method
NB: Thanks to @Rmano. This method doesn’t work with zsh shell.
This will list all commands in your $PATH environment variable.
To store the result in a file you can redirect the output to a file.
Note that this will return an error if any directory names in your $PATH contain spaces. In that case, use this instead:
while read -d ':' dir; do echo "$dir"; done
Second Method
compgen -c | sort -u > commands && less commands
Third Method
Another method is a double Tab click.
Fourth Method
Another method using find command:
Notice that the first command works in bash but not in zsh , which has word split disabled by default. refining-linux.org/archives/38/…
If you are using bash, which is the default shell in all official Ubuntu flavors, run compgen -c to see the available commands including aliases.
Even the commands for gui-based programs are included. So if you do compgen -c | grep thunar and you have the Thunar file manager installed, you'll see commands related to Thunar as well.
@vasa1: Could this answer be more general? I mean it only provides the solution for bash, but as Braiam noted it doesn't work for zsh. If possible could you please expand the answer to cater to a larger audience - obviously only if you know the answer 🙂
Open terminal Ctrl + Alt + t and run this command:
This will list all commands and a simple description of each command.
If you want to save the list you can redirect the result into an output file
whatis `compgen -c` > listOfCommands.txt
So why I used whatis command. The command man whatis gives:
Each manual page has a short description available within it.
whatis searches the manual page names and displays the manual page descrip‐ tions of any name matched.
so in easy words whatis give a general. description of each command
+1 for additional info. whatis `compgen -c` | sort > listOfCommands.txt will help go get in sort list.
Another useful command: apropos
Open up a terminal and press the Tab key twice.
@LorenzoAncora why is it not standard? Does not all Ubuntu have the autocompletion with double Tab as standard behaviour?
Default != standard: in a future maybe we'll have a console that does not support that mechanism, because it's not standard; more, the TAB standard may serve a different function. A standard procedure is listing the content of 'bin', because is part of the official FHS standard and any Linux/Unix system has that directory. The correct functionality (and the ability of the community to help the users) of Ubuntu is ensured by the respect of the standards.
Ok, thanks for the explanation 🙂 I thought that the standard behaviout of the double Tab on Ubuntu was to list the content of PATH 🙂
@LorenzoAncora Listing the contents of any one directory will not show anywhere close to all executable commands. Listing the contents of all PATH directories will not show shell builtins with no corresponding executable (such as cd ). Pressing Tab twice overcomes both these severe limitations. If someone had asked how to show all commands on an arbitrary GNU/Linux system, one might argue that Tab completion is not an adequate solution. Of course anything might change in Ubuntu in the future but the likelihood of tab completion in the default interactive shell going away is minuscule.
A list of command depends greatly on what you have installed, but there are cheats to list all commands. The following works on most bourne-like shells:
- Press Tab twice.
- Use find to find all executables:
ls /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin
Open a terminal window (GNOME terminal is OK, also a configured xTerm).
Your options are:
- By pressing the TAB key ("-><-") twice, you'll complete any command in the console and, if the line is empty, you'll get the number and the names of all available commands. Please note that it may require some time and may list semi-administrative utilities. NOTE: this isn't a standard, for a "cross-shell" way see the other options.
- Use man -k NAME to search for a command (or part of it) and man COMMAND to obtain the manual for that command. Not al commands have a system manual; reading the man before using any administrative utility is always a good idea; trust me.
- Use Midnight Commander ( mc ) to have a nice console (curses) GUI to manage the system and the file system. You may have to install it from your package manager. Don't worry; it is safe and extremely common software.
NOTE: It's made for when you have confusion or difficulty in using the file system. - Use ls /bin | more to know all exential administrative executables; ls /sbin | more for common administrative executables.
- Use ls /usr/sbin | more to know all user executables; ls /usr/sbin | more will give a very huge list of user executables and libraries.
NOTE: If the output from more exceeds one page (screenful), you'll have to scroll py pressing "Page Up" and "Page Down" or spacebar.
You can use COMMAND | grep TEXT to filter the output.
If you have more questions comment under here and don't forget to check the tick next to the answer if I helped you.
Have a nice experience.
Usually, most executables are in /usr/bin , which you haven't mentioned here. Also there's /sbin , which contains executables often used for system administration, such as usermod and ifconfig . And many systems have other binary directories as well, like /usr/games and /usr/local/bin . See Filesystem hierarchy standard and man 7 hier . You might want to expand this to mention important directories for executables besides /bin and /usr/sbin .
This is a bit old, but can be still relevant
And information on using the Ubuntu terminal
the above page has more links at the end which will help you finding more commands for Ubuntu.