LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 11-02-2010, 09:23 AM   #1
tospo
LQ Newbie
 
Registered: Dec 2007
Posts: 17

Rep: Reputation: 0
echo commands in BASH script to STDOUT


Hi,

I'm looking for a good way of printing certain commands from a BASH script to STDOUT. This is going into a log file in the end. I don't want every command to be in there, just a few critical ones.
I know about
Code:
#!/usr/bin/bash -x
for echoing every command to the screen and also that I can do
Code:
set -x
some_command
set +x
to switch on the debugger for a single command.
The latter is what I'm using now but it produces a lot of annoying "+ set+x" lines in the output, because it will echo both, "some_command" and the next "set" command.
I would like to get rid of the redundant "+ set +x" lines.
My question: is there a better way of echoing commands to STDOUT then -x?

Thanks for your help!
 
Old 11-02-2010, 09:58 AM   #2
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376
Hi,

Why not add 1>$LOGFILE 2>&1 (or alike) to the critical commands instead of using set -/+x?

This will also give you the possibility to put output into different logfiles and you can split normal output (stdout) from errors (stderr).

Example:
Code:
#!/bin/bash

LOG_COMMANDS="/path/to/commands.log"
LOG_NORMAL="/path/to/logfile"

some_command 1>$LOG_NORMAL 2>$LOG_COMMANDS

other_command 1>$LOG_COMMANDS 2>&1
Also have a look at the tee command, which gives you the opportunity print output to screen and to a logfile.

Hope this helps.
 
Old 11-02-2010, 11:23 AM   #3
tospo
LQ Newbie
 
Registered: Dec 2007
Posts: 17

Original Poster
Rep: Reputation: 0
thanks druuna, but that's not quite what I meant.

Redirection would only give me the STDERR and/or STDOUT of the command but I want to log the actual command itself (sorry if that was unclear).

So if my script contains the line
Code:
ls ${cwd}/thefiles_*
then I want the log to show something like

Code:
ls working_dir/thefiles_*
not the result of that command.
 
Old 11-02-2010, 11:53 AM   #4
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376Reputation: 2376
Hi,

Ok, clear.

Only thing that comes to mind: echo the command(s):
Code:
#!/bin/bash

echo "ls ${cwd}/thefiles_*"
ls ${cwd}/thefiles_*
I still believe you might want to have a look at the tee command (in combination with the echo command). This way you can see what is happening as the script runs _and_ have a log file to check later on.

Hope this helps.
 
Old 11-02-2010, 02:43 PM   #5
tospo
LQ Newbie
 
Registered: Dec 2007
Posts: 17

Original Poster
Rep: Reputation: 0
Thanks again druuna.
Yes, that can be done and I also used to do it like that but there are two problems:
1) duplication: it is very easy to change the command but forget to change the echo statment and the log will be wrong
2) to avoid 1, you would need to put the command into a variable and then use the variable to run the command. That works but I find myself in escape-and-quote hell very quickly, especially if you have longer commands where quoting and escaping is already a challange sometimes.

I guess the set -x option is probably the best for now. It works and I guess I might have to live with all those "set +x" lines in my log file for now.
 
Old 11-02-2010, 03:15 PM   #6
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,563
Blog Entries: 29

Rep: Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179
Here are Greg's thoughts on the subject. I've tried using the array technique but it gets cumbersome; implementing it in a function would be tidier. AFAIK there's no way to use command history to get what you want.
 
1 members found this post helpful.
Old 11-03-2010, 05:27 AM   #7
tospo
LQ Newbie
 
Registered: Dec 2007
Posts: 17

Original Poster
Rep: Reputation: 0
Thanks a lot catkin, that blog post was exactly what I was looking for!
OK, from that I gather that set -/+x is the best solution already and I guess I have to live with those pesky "set +x" lines in my log and maybe remove them afterwards with grep. I think that's still better than copy/pasting the command, forgetting to update the echo statement and then wondering later why that command lead to that error where it was really a different command that caused it.
 
Old 11-03-2010, 09:40 AM   #8
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,563
Blog Entries: 29

Rep: Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179
Quote:
Originally Posted by tospo View Post
Thanks a lot catkin, that blog post was exactly what I was looking for!
OK, from that I gather that set -/+x is the best solution already and I guess I have to live with those pesky "set +x" lines in my log and maybe remove them afterwards with grep. I think that's still better than copy/pasting the command, forgetting to update the echo statement and then wondering later why that command lead to that error where it was really a different command that caused it.
Greg's WIKI is a great bash resource.

I can't think of a better solution than you have described. Not pretty but the best we can do with bash (until someone finds out differently -- there's always something to learn with bash )
 
Old 11-03-2010, 10:24 AM   #9
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959
Why not write a function that echoes the command before its execution? In this case if you change the command in a later revision of the script, the function will take care of recording the changes. Example:
Code:
function echo_cmd () {
  echo "$PS4$@" 1>&2
  "$@"
}
The only (not sure about this) caveat is to call the function for every command inside a piped chain, i.e.
Code:
$ echo_cmd echo string | echo_cmd cut -c 1-3
+ cut -c 1-3
+ echo string
str
which is exactly the same output as that one produced by set -x. Regarding redirection, it will be processed in the usual way and similarly to set -x the echoed command will be sent to standard error.

Edit: ok... found another caveat: command substitution is not treated as set -x, since it is performed by the invoking shell, not inside the function. Hmm... maybe this is not a good approach!

Last edited by colucix; 11-03-2010 at 10:31 AM. Reason: More doubts......
 
Old 11-03-2010, 11:12 AM   #10
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Servers: Debian Squeeze and Wheezy. Desktop: Slackware64 14.0. Netbook: Slackware 13.37
Posts: 8,563
Blog Entries: 29

Rep: Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179Reputation: 1179
colucix's solution works for bare commands but not for command substitution (as he has already mentioned) or for I/O redirection or for pipelines. It would be difficult to write a function that did deal with these; how would it deal with the apparently innocuous echo "|" foo or echo '$( ls ) > /tmp/ls.output' ? The function would have no way, passed a series of words that make up a command, to know if they were simply strings or if they had special meaning for command execution. Any sequence of characters are possible so no "escaping" to tell the function that "this word has a special meaning for command execution" is robustly possible and, even it it were "good enough" it would be messy for the calling code.

All-in-all, stripping the "set +x"s out of the log is simpler!

Last edited by catkin; 11-03-2010 at 11:13 AM. Reason: Corrected "know" to "no"
 
1 members found this post helpful.
  


Reply

Tags
bash, echo


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
redirecting BASH script stdout/stderr from the script itself Hewson Linux - General 4 04-18-2008 04:32 PM
Bash scripts do not echo commands sean@responsivedata. Linux - Newbie 9 01-17-2006 11:25 AM
Bash scripts do not echo commands sean@responsivedata. Programming 7 01-17-2006 10:08 AM
Bash scripts do not echo commands sean@responsivedata. Linux - Software 3 01-13-2006 10:03 PM
Bash Script, no new line for echo command jorisb Linux - General 5 11-05-2005 01:08 AM


All times are GMT -5. The time now is 04:44 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration