Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show commands without executing them

Tags:

bash

I often interactively loop over e.g. my files and want to perform a specific operation on all of them, let's say I'd like to rename all files:

for file in $(ls); do mv "$file" "${file}_new"; done 

This works fine. But before invoking this command, I'd like to see what it actually does, so I would add an echo in front

for file in $(ls); do echo mv "$file" "${file}_new"; done 

it then shows me all the commands it would invoke. If I'm happy with them, I remove the echo and execute it.

However, when the commands are a bit more subtle maybe including pipes or more than one command, this doesn't work anymore. Of course I could use ' so the special characters don't get interpreted, but then I don't have parameter expansion. I could also escape the special characters, but this would get very tedious.

My question is, what's the best way to do this? I've read in man bash about the option -n, which does "Read commands but do not execute them. This may be used to check a shell script for syntax errors. This is ignored by interactive shells." This is exactly what I need, but I need it for an interactive shell. Note that the options -x or -v do not help, as it will not only show the command, but also invoke it and then it might be too late already.

like image 826
pfnuesel Avatar asked Oct 01 '13 11:10

pfnuesel


People also ask

What does the command echo $0 Display?

As explained in this comment on that answer you link to, echo $0 simply shows you the name of the currently running process: $0 is the name of the running process. If you use it inside of a shell then it will return the name of the shell. If you use it inside of a script, it will be the name of the script.

How do I run a command without alias?

Use a “\” (backslash) before the command to run it without the alias. The backslash escape character can be used before a shell command to override any aliases.

How do I run a shell script without execution?

For shell scripts without execute permissions, you will need to pass the script as an argument to your choice of interpreter. Here the execute permissions are checked for your shell interpreter and not the script itself. So you should have execute for /bin/sh and your script can have only read permissions.

How do I display exit status in last command?

To display the exit code for the last command you ran on the command line, use the following command: $ echo $? The displayed response contains no pomp or circumstance. It's simply a number.


2 Answers

There is no option for "dry run" as explained by devnull but there is a simple workaround:

debug= #debug=echo  $debug mv "$file" "${file}_new" 

If you remove the comment from the second assignment (without changing anything else), you enable "dry run" for the dangerous mv command.

A more elaborate approach would be to check some condition (like a command line option):

debug= if [[ ...enable dry run?... ]]; then     debug=echo fi 

Note: The empty assignment is only necessary when you have the option -u ("Treat unset variables as an error when substituting.") enabled.

Important: This won't work well, when your commands use redirections (because the shell will always do them before the command is even started).

like image 83
Aaron Digulla Avatar answered Sep 19 '22 21:09

Aaron Digulla


This thread would tell you why the option to show commands instead of executing those (a.k.a dry run) would never be implemented for bash.

Refer to the response from Eric Blake:

> My question is why can't such an option or be provided,

A little thought would show why this will never be implemented. What would such an option output for the following:

if complex_command; then   foo=command1 else   foo=command2 fi $foo args 

On the line for $foo args, there is no way to know what $foo expands to unless you have previously executed (not just scanned) the complex_command. Therefore, there is no way to dry run what the final results will be without running things, but running things is counter to the goal of a dry run.

That said, you might be interested in the bashdb project, which uses bash hooks to provide a debugger interface where you can single-step through a bash script; it's not the same as telling you what the script would do, but it at least lets you control how much or little of the script is actually run.

like image 27
devnull Avatar answered Sep 19 '22 21:09

devnull