Redirect stdout and/or stderr to path in variable

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite












How do I redirect stdout and/or stderr to a path I have specified in a variable? Note: I don't want to overwrite the variable itself, I want to make std[xxx] write to the file specified in the variable.



For example- a simple script that, if the scp command fails, instead of printing the failure message to stderr or stdout (I'm not sure to which it outputs when fail), it outputs it to a specified log file. The path to the log file is stored in the $LOG variable:



LOG=/path/to/file.log
scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
whatever
else
# else log both stdout/stderr to $LOG file
&>"$LOG"
# DEBUG - print contents of $LOG var for testing purposes
printf "$LOG"


The result of this script doesn't show anything in the /path/to/file.log file and simple prints /path/to/file.log to stdout. So it's as if nothing was written from &>.



I've already confirmed my particular scp command works, so I know that's not a potential issue.



Or is this even the most proper way to handle custom log files? Is there a better practice for configuring your own logging system than storing paths to log files in variables?







share|improve this question


















  • 3




    The redirection would have to happen before scp is run, or with the scp line, not after the scp has already gone away.
    – thrig
    Nov 18 '17 at 15:05










  • Why not unconditionally write to a temporary file and then test for success/failure? If failure, add the output to your permanent log file or print and discard it.
    – JRFerguson
    Nov 18 '17 at 15:13














up vote
1
down vote

favorite












How do I redirect stdout and/or stderr to a path I have specified in a variable? Note: I don't want to overwrite the variable itself, I want to make std[xxx] write to the file specified in the variable.



For example- a simple script that, if the scp command fails, instead of printing the failure message to stderr or stdout (I'm not sure to which it outputs when fail), it outputs it to a specified log file. The path to the log file is stored in the $LOG variable:



LOG=/path/to/file.log
scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
whatever
else
# else log both stdout/stderr to $LOG file
&>"$LOG"
# DEBUG - print contents of $LOG var for testing purposes
printf "$LOG"


The result of this script doesn't show anything in the /path/to/file.log file and simple prints /path/to/file.log to stdout. So it's as if nothing was written from &>.



I've already confirmed my particular scp command works, so I know that's not a potential issue.



Or is this even the most proper way to handle custom log files? Is there a better practice for configuring your own logging system than storing paths to log files in variables?







share|improve this question


















  • 3




    The redirection would have to happen before scp is run, or with the scp line, not after the scp has already gone away.
    – thrig
    Nov 18 '17 at 15:05










  • Why not unconditionally write to a temporary file and then test for success/failure? If failure, add the output to your permanent log file or print and discard it.
    – JRFerguson
    Nov 18 '17 at 15:13












up vote
1
down vote

favorite









up vote
1
down vote

favorite











How do I redirect stdout and/or stderr to a path I have specified in a variable? Note: I don't want to overwrite the variable itself, I want to make std[xxx] write to the file specified in the variable.



For example- a simple script that, if the scp command fails, instead of printing the failure message to stderr or stdout (I'm not sure to which it outputs when fail), it outputs it to a specified log file. The path to the log file is stored in the $LOG variable:



LOG=/path/to/file.log
scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
whatever
else
# else log both stdout/stderr to $LOG file
&>"$LOG"
# DEBUG - print contents of $LOG var for testing purposes
printf "$LOG"


The result of this script doesn't show anything in the /path/to/file.log file and simple prints /path/to/file.log to stdout. So it's as if nothing was written from &>.



I've already confirmed my particular scp command works, so I know that's not a potential issue.



Or is this even the most proper way to handle custom log files? Is there a better practice for configuring your own logging system than storing paths to log files in variables?







share|improve this question














How do I redirect stdout and/or stderr to a path I have specified in a variable? Note: I don't want to overwrite the variable itself, I want to make std[xxx] write to the file specified in the variable.



For example- a simple script that, if the scp command fails, instead of printing the failure message to stderr or stdout (I'm not sure to which it outputs when fail), it outputs it to a specified log file. The path to the log file is stored in the $LOG variable:



LOG=/path/to/file.log
scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
whatever
else
# else log both stdout/stderr to $LOG file
&>"$LOG"
# DEBUG - print contents of $LOG var for testing purposes
printf "$LOG"


The result of this script doesn't show anything in the /path/to/file.log file and simple prints /path/to/file.log to stdout. So it's as if nothing was written from &>.



I've already confirmed my particular scp command works, so I know that's not a potential issue.



Or is this even the most proper way to handle custom log files? Is there a better practice for configuring your own logging system than storing paths to log files in variables?









share|improve this question













share|improve this question




share|improve this question








edited Nov 18 '17 at 15:33









Jeff Schaller

32.1k849109




32.1k849109










asked Nov 18 '17 at 15:04









Willman

84




84







  • 3




    The redirection would have to happen before scp is run, or with the scp line, not after the scp has already gone away.
    – thrig
    Nov 18 '17 at 15:05










  • Why not unconditionally write to a temporary file and then test for success/failure? If failure, add the output to your permanent log file or print and discard it.
    – JRFerguson
    Nov 18 '17 at 15:13












  • 3




    The redirection would have to happen before scp is run, or with the scp line, not after the scp has already gone away.
    – thrig
    Nov 18 '17 at 15:05










  • Why not unconditionally write to a temporary file and then test for success/failure? If failure, add the output to your permanent log file or print and discard it.
    – JRFerguson
    Nov 18 '17 at 15:13







3




3




The redirection would have to happen before scp is run, or with the scp line, not after the scp has already gone away.
– thrig
Nov 18 '17 at 15:05




The redirection would have to happen before scp is run, or with the scp line, not after the scp has already gone away.
– thrig
Nov 18 '17 at 15:05












Why not unconditionally write to a temporary file and then test for success/failure? If failure, add the output to your permanent log file or print and discard it.
– JRFerguson
Nov 18 '17 at 15:13




Why not unconditionally write to a temporary file and then test for success/failure? If failure, add the output to your permanent log file or print and discard it.
– JRFerguson
Nov 18 '17 at 15:13










2 Answers
2






active

oldest

votes

















up vote
0
down vote



accepted










It looks like you're trying to log the output after you run the command, which isn't possible.



If you want to log the output of the scp command unconditionally, then you just have to include the redirection operator on the same line as the command itself, i.e.:



&>"$LOG" scp file1 host@remote


If you want to only save the log output if the command fails (as it appears you're trying to do in your code), then how about redirecting the output to a temporary file and then moving the file to the desired location afterwards? It might look something like this:



#!/bin/bash

# Set path the real log file location
LOG=/path/to/file.log

# Create a temporary file to capture standard output and standard error
TEMPLOG="$(mktemp)"

# Run command and redirect output to temporary logfile
2>"$TEMPLOG" scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
echo 'Command successful!'

# else log both stdout/stderr to $LOG file
else
# Move the log file from the temporary location to the desired location
mv "$TEMPLOG" "$LOG"

# DEBUG - print contents of $LOG var for testing purposes
printf "$LOG"
fi





share|improve this answer






















  • Ok I see. I'd thought &> would've been handled in the same way $? is- the output of the last command. But I see now that $? is the "exit status", NOT "standard output" of the prev. command. Ok so this answers the main question, but would this be the most elegant solution for custom logging? Is there a way to avoid using temp files for output? I can see this getting out of hand in very large/multiple scripts or with multiple different log files.
    – Willman
    Nov 18 '17 at 16:30











  • @Willman I'm not sure what the most elegant way would be to implement logging in a shell script. If there's something better than just redirecting the output you want to a file then I haven't seen it. If you're on Linux then you might also consider using the logger command to write to the system logs, but I don't have any experience with that and I'm not sure that there would be any benefit to it. Maybe check out this post: Understand logging in Linux
    – igal
    Nov 18 '17 at 16:46











  • @Willman The mktemp command should make sure that there are no naming conflicts. Why would the temporary files get out of hand? To me it seems like the version of your script which temporary files is no less manageable than the the version of your script without them.
    – igal
    Nov 18 '17 at 16:47










  • Ok so &>"$LOG" scp file host@remote successfully sends output to the /path/to/file.log like I want. This is the elegant solution I was talking about. I just didn't want to create unnecessary temp files on disk when I can just use I/O redirection and bash variables instead. (BTW to answer my side question- scp prints to stdout when there is a permissions issue on remote dir, not stderr for some reason).
    – Willman
    Nov 18 '17 at 16:57










  • @Willman Ah, ok. Based on the example code in your question I thought you only wanted to write the log file if the command failed. If you just wanted to log all of the output no matter what then that one-liner is definitely the most straight-forward thing to do.
    – igal
    Nov 18 '17 at 17:09

















up vote
0
down vote













It looks like you were eventually satisfied with the outcome of this question but I propose something different.



#!/bin/bash
LOG=/path/to/file.log
DEBUG=0 # 0 = True, 1 = False
OUTPUT=$(scp file1 host@remote 2>&1)

# do 'whatever' if scp command succeeds:
if [ $? -eq 0 ];
then
echo "Success"
elif [[ DEBUG -eq 0 ]]
# else log both stdout/stderr to $LOG file and user
# DEBUG - Use tee to display $LOG contents efficiently
printf "$OUTPUT" | tee $LOG
else
# Send output to $LOG
printf "$OUTPUT" >> $LOG
fi


Essentially capture STDIN/STDOUT in a variable no matter what, then if success do 'whatever' but if failure redirect STDIN/STDOUT to $LOG. Additionally with the $DEBUG flag you can tee the contents of $OUTPUT to the display and $LOG simultaneously.



Also for integer comparison you really should use -eq instead of = or ==






share|improve this answer






















  • Note that the value of $? at the point where you access it will be the return code of the assignment DEBUG=0. $? will be non-zero if that assignment fails (which is possible if DEBUG is a read-only variable). Also note that your calls to echo will remove any newlines from the value $OUTPUT, and that there is also a then missing.
    – Kusalananda
    Apr 6 at 14:49











  • Ah, yeah the $? is referencing the wrong thing, DEBUG was an afterthought but I'll fix it. echo does in fact remove the newlines so printf is better if you want to preserve. Which then are you referring to, it is on the line after the if statement just to be consistent with the original post?
    – Amos Baker
    Apr 6 at 16:04











Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f405445%2fredirect-stdout-and-or-stderr-to-path-in-variable%23new-answer', 'question_page');

);

Post as a guest






























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote



accepted










It looks like you're trying to log the output after you run the command, which isn't possible.



If you want to log the output of the scp command unconditionally, then you just have to include the redirection operator on the same line as the command itself, i.e.:



&>"$LOG" scp file1 host@remote


If you want to only save the log output if the command fails (as it appears you're trying to do in your code), then how about redirecting the output to a temporary file and then moving the file to the desired location afterwards? It might look something like this:



#!/bin/bash

# Set path the real log file location
LOG=/path/to/file.log

# Create a temporary file to capture standard output and standard error
TEMPLOG="$(mktemp)"

# Run command and redirect output to temporary logfile
2>"$TEMPLOG" scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
echo 'Command successful!'

# else log both stdout/stderr to $LOG file
else
# Move the log file from the temporary location to the desired location
mv "$TEMPLOG" "$LOG"

# DEBUG - print contents of $LOG var for testing purposes
printf "$LOG"
fi





share|improve this answer






















  • Ok I see. I'd thought &> would've been handled in the same way $? is- the output of the last command. But I see now that $? is the "exit status", NOT "standard output" of the prev. command. Ok so this answers the main question, but would this be the most elegant solution for custom logging? Is there a way to avoid using temp files for output? I can see this getting out of hand in very large/multiple scripts or with multiple different log files.
    – Willman
    Nov 18 '17 at 16:30











  • @Willman I'm not sure what the most elegant way would be to implement logging in a shell script. If there's something better than just redirecting the output you want to a file then I haven't seen it. If you're on Linux then you might also consider using the logger command to write to the system logs, but I don't have any experience with that and I'm not sure that there would be any benefit to it. Maybe check out this post: Understand logging in Linux
    – igal
    Nov 18 '17 at 16:46











  • @Willman The mktemp command should make sure that there are no naming conflicts. Why would the temporary files get out of hand? To me it seems like the version of your script which temporary files is no less manageable than the the version of your script without them.
    – igal
    Nov 18 '17 at 16:47










  • Ok so &>"$LOG" scp file host@remote successfully sends output to the /path/to/file.log like I want. This is the elegant solution I was talking about. I just didn't want to create unnecessary temp files on disk when I can just use I/O redirection and bash variables instead. (BTW to answer my side question- scp prints to stdout when there is a permissions issue on remote dir, not stderr for some reason).
    – Willman
    Nov 18 '17 at 16:57










  • @Willman Ah, ok. Based on the example code in your question I thought you only wanted to write the log file if the command failed. If you just wanted to log all of the output no matter what then that one-liner is definitely the most straight-forward thing to do.
    – igal
    Nov 18 '17 at 17:09














up vote
0
down vote



accepted










It looks like you're trying to log the output after you run the command, which isn't possible.



If you want to log the output of the scp command unconditionally, then you just have to include the redirection operator on the same line as the command itself, i.e.:



&>"$LOG" scp file1 host@remote


If you want to only save the log output if the command fails (as it appears you're trying to do in your code), then how about redirecting the output to a temporary file and then moving the file to the desired location afterwards? It might look something like this:



#!/bin/bash

# Set path the real log file location
LOG=/path/to/file.log

# Create a temporary file to capture standard output and standard error
TEMPLOG="$(mktemp)"

# Run command and redirect output to temporary logfile
2>"$TEMPLOG" scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
echo 'Command successful!'

# else log both stdout/stderr to $LOG file
else
# Move the log file from the temporary location to the desired location
mv "$TEMPLOG" "$LOG"

# DEBUG - print contents of $LOG var for testing purposes
printf "$LOG"
fi





share|improve this answer






















  • Ok I see. I'd thought &> would've been handled in the same way $? is- the output of the last command. But I see now that $? is the "exit status", NOT "standard output" of the prev. command. Ok so this answers the main question, but would this be the most elegant solution for custom logging? Is there a way to avoid using temp files for output? I can see this getting out of hand in very large/multiple scripts or with multiple different log files.
    – Willman
    Nov 18 '17 at 16:30











  • @Willman I'm not sure what the most elegant way would be to implement logging in a shell script. If there's something better than just redirecting the output you want to a file then I haven't seen it. If you're on Linux then you might also consider using the logger command to write to the system logs, but I don't have any experience with that and I'm not sure that there would be any benefit to it. Maybe check out this post: Understand logging in Linux
    – igal
    Nov 18 '17 at 16:46











  • @Willman The mktemp command should make sure that there are no naming conflicts. Why would the temporary files get out of hand? To me it seems like the version of your script which temporary files is no less manageable than the the version of your script without them.
    – igal
    Nov 18 '17 at 16:47










  • Ok so &>"$LOG" scp file host@remote successfully sends output to the /path/to/file.log like I want. This is the elegant solution I was talking about. I just didn't want to create unnecessary temp files on disk when I can just use I/O redirection and bash variables instead. (BTW to answer my side question- scp prints to stdout when there is a permissions issue on remote dir, not stderr for some reason).
    – Willman
    Nov 18 '17 at 16:57










  • @Willman Ah, ok. Based on the example code in your question I thought you only wanted to write the log file if the command failed. If you just wanted to log all of the output no matter what then that one-liner is definitely the most straight-forward thing to do.
    – igal
    Nov 18 '17 at 17:09












up vote
0
down vote



accepted







up vote
0
down vote



accepted






It looks like you're trying to log the output after you run the command, which isn't possible.



If you want to log the output of the scp command unconditionally, then you just have to include the redirection operator on the same line as the command itself, i.e.:



&>"$LOG" scp file1 host@remote


If you want to only save the log output if the command fails (as it appears you're trying to do in your code), then how about redirecting the output to a temporary file and then moving the file to the desired location afterwards? It might look something like this:



#!/bin/bash

# Set path the real log file location
LOG=/path/to/file.log

# Create a temporary file to capture standard output and standard error
TEMPLOG="$(mktemp)"

# Run command and redirect output to temporary logfile
2>"$TEMPLOG" scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
echo 'Command successful!'

# else log both stdout/stderr to $LOG file
else
# Move the log file from the temporary location to the desired location
mv "$TEMPLOG" "$LOG"

# DEBUG - print contents of $LOG var for testing purposes
printf "$LOG"
fi





share|improve this answer














It looks like you're trying to log the output after you run the command, which isn't possible.



If you want to log the output of the scp command unconditionally, then you just have to include the redirection operator on the same line as the command itself, i.e.:



&>"$LOG" scp file1 host@remote


If you want to only save the log output if the command fails (as it appears you're trying to do in your code), then how about redirecting the output to a temporary file and then moving the file to the desired location afterwards? It might look something like this:



#!/bin/bash

# Set path the real log file location
LOG=/path/to/file.log

# Create a temporary file to capture standard output and standard error
TEMPLOG="$(mktemp)"

# Run command and redirect output to temporary logfile
2>"$TEMPLOG" scp file1 host@remote

# do 'whatever' if scp command succeeds:
if [ $? = 0 ];
then
echo 'Command successful!'

# else log both stdout/stderr to $LOG file
else
# Move the log file from the temporary location to the desired location
mv "$TEMPLOG" "$LOG"

# DEBUG - print contents of $LOG var for testing purposes
printf "$LOG"
fi






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 18 '17 at 17:07

























answered Nov 18 '17 at 15:38









igal

4,830930




4,830930











  • Ok I see. I'd thought &> would've been handled in the same way $? is- the output of the last command. But I see now that $? is the "exit status", NOT "standard output" of the prev. command. Ok so this answers the main question, but would this be the most elegant solution for custom logging? Is there a way to avoid using temp files for output? I can see this getting out of hand in very large/multiple scripts or with multiple different log files.
    – Willman
    Nov 18 '17 at 16:30











  • @Willman I'm not sure what the most elegant way would be to implement logging in a shell script. If there's something better than just redirecting the output you want to a file then I haven't seen it. If you're on Linux then you might also consider using the logger command to write to the system logs, but I don't have any experience with that and I'm not sure that there would be any benefit to it. Maybe check out this post: Understand logging in Linux
    – igal
    Nov 18 '17 at 16:46











  • @Willman The mktemp command should make sure that there are no naming conflicts. Why would the temporary files get out of hand? To me it seems like the version of your script which temporary files is no less manageable than the the version of your script without them.
    – igal
    Nov 18 '17 at 16:47










  • Ok so &>"$LOG" scp file host@remote successfully sends output to the /path/to/file.log like I want. This is the elegant solution I was talking about. I just didn't want to create unnecessary temp files on disk when I can just use I/O redirection and bash variables instead. (BTW to answer my side question- scp prints to stdout when there is a permissions issue on remote dir, not stderr for some reason).
    – Willman
    Nov 18 '17 at 16:57










  • @Willman Ah, ok. Based on the example code in your question I thought you only wanted to write the log file if the command failed. If you just wanted to log all of the output no matter what then that one-liner is definitely the most straight-forward thing to do.
    – igal
    Nov 18 '17 at 17:09
















  • Ok I see. I'd thought &> would've been handled in the same way $? is- the output of the last command. But I see now that $? is the "exit status", NOT "standard output" of the prev. command. Ok so this answers the main question, but would this be the most elegant solution for custom logging? Is there a way to avoid using temp files for output? I can see this getting out of hand in very large/multiple scripts or with multiple different log files.
    – Willman
    Nov 18 '17 at 16:30











  • @Willman I'm not sure what the most elegant way would be to implement logging in a shell script. If there's something better than just redirecting the output you want to a file then I haven't seen it. If you're on Linux then you might also consider using the logger command to write to the system logs, but I don't have any experience with that and I'm not sure that there would be any benefit to it. Maybe check out this post: Understand logging in Linux
    – igal
    Nov 18 '17 at 16:46











  • @Willman The mktemp command should make sure that there are no naming conflicts. Why would the temporary files get out of hand? To me it seems like the version of your script which temporary files is no less manageable than the the version of your script without them.
    – igal
    Nov 18 '17 at 16:47










  • Ok so &>"$LOG" scp file host@remote successfully sends output to the /path/to/file.log like I want. This is the elegant solution I was talking about. I just didn't want to create unnecessary temp files on disk when I can just use I/O redirection and bash variables instead. (BTW to answer my side question- scp prints to stdout when there is a permissions issue on remote dir, not stderr for some reason).
    – Willman
    Nov 18 '17 at 16:57










  • @Willman Ah, ok. Based on the example code in your question I thought you only wanted to write the log file if the command failed. If you just wanted to log all of the output no matter what then that one-liner is definitely the most straight-forward thing to do.
    – igal
    Nov 18 '17 at 17:09















Ok I see. I'd thought &> would've been handled in the same way $? is- the output of the last command. But I see now that $? is the "exit status", NOT "standard output" of the prev. command. Ok so this answers the main question, but would this be the most elegant solution for custom logging? Is there a way to avoid using temp files for output? I can see this getting out of hand in very large/multiple scripts or with multiple different log files.
– Willman
Nov 18 '17 at 16:30





Ok I see. I'd thought &> would've been handled in the same way $? is- the output of the last command. But I see now that $? is the "exit status", NOT "standard output" of the prev. command. Ok so this answers the main question, but would this be the most elegant solution for custom logging? Is there a way to avoid using temp files for output? I can see this getting out of hand in very large/multiple scripts or with multiple different log files.
– Willman
Nov 18 '17 at 16:30













@Willman I'm not sure what the most elegant way would be to implement logging in a shell script. If there's something better than just redirecting the output you want to a file then I haven't seen it. If you're on Linux then you might also consider using the logger command to write to the system logs, but I don't have any experience with that and I'm not sure that there would be any benefit to it. Maybe check out this post: Understand logging in Linux
– igal
Nov 18 '17 at 16:46





@Willman I'm not sure what the most elegant way would be to implement logging in a shell script. If there's something better than just redirecting the output you want to a file then I haven't seen it. If you're on Linux then you might also consider using the logger command to write to the system logs, but I don't have any experience with that and I'm not sure that there would be any benefit to it. Maybe check out this post: Understand logging in Linux
– igal
Nov 18 '17 at 16:46













@Willman The mktemp command should make sure that there are no naming conflicts. Why would the temporary files get out of hand? To me it seems like the version of your script which temporary files is no less manageable than the the version of your script without them.
– igal
Nov 18 '17 at 16:47




@Willman The mktemp command should make sure that there are no naming conflicts. Why would the temporary files get out of hand? To me it seems like the version of your script which temporary files is no less manageable than the the version of your script without them.
– igal
Nov 18 '17 at 16:47












Ok so &>"$LOG" scp file host@remote successfully sends output to the /path/to/file.log like I want. This is the elegant solution I was talking about. I just didn't want to create unnecessary temp files on disk when I can just use I/O redirection and bash variables instead. (BTW to answer my side question- scp prints to stdout when there is a permissions issue on remote dir, not stderr for some reason).
– Willman
Nov 18 '17 at 16:57




Ok so &>"$LOG" scp file host@remote successfully sends output to the /path/to/file.log like I want. This is the elegant solution I was talking about. I just didn't want to create unnecessary temp files on disk when I can just use I/O redirection and bash variables instead. (BTW to answer my side question- scp prints to stdout when there is a permissions issue on remote dir, not stderr for some reason).
– Willman
Nov 18 '17 at 16:57












@Willman Ah, ok. Based on the example code in your question I thought you only wanted to write the log file if the command failed. If you just wanted to log all of the output no matter what then that one-liner is definitely the most straight-forward thing to do.
– igal
Nov 18 '17 at 17:09




@Willman Ah, ok. Based on the example code in your question I thought you only wanted to write the log file if the command failed. If you just wanted to log all of the output no matter what then that one-liner is definitely the most straight-forward thing to do.
– igal
Nov 18 '17 at 17:09












up vote
0
down vote













It looks like you were eventually satisfied with the outcome of this question but I propose something different.



#!/bin/bash
LOG=/path/to/file.log
DEBUG=0 # 0 = True, 1 = False
OUTPUT=$(scp file1 host@remote 2>&1)

# do 'whatever' if scp command succeeds:
if [ $? -eq 0 ];
then
echo "Success"
elif [[ DEBUG -eq 0 ]]
# else log both stdout/stderr to $LOG file and user
# DEBUG - Use tee to display $LOG contents efficiently
printf "$OUTPUT" | tee $LOG
else
# Send output to $LOG
printf "$OUTPUT" >> $LOG
fi


Essentially capture STDIN/STDOUT in a variable no matter what, then if success do 'whatever' but if failure redirect STDIN/STDOUT to $LOG. Additionally with the $DEBUG flag you can tee the contents of $OUTPUT to the display and $LOG simultaneously.



Also for integer comparison you really should use -eq instead of = or ==






share|improve this answer






















  • Note that the value of $? at the point where you access it will be the return code of the assignment DEBUG=0. $? will be non-zero if that assignment fails (which is possible if DEBUG is a read-only variable). Also note that your calls to echo will remove any newlines from the value $OUTPUT, and that there is also a then missing.
    – Kusalananda
    Apr 6 at 14:49











  • Ah, yeah the $? is referencing the wrong thing, DEBUG was an afterthought but I'll fix it. echo does in fact remove the newlines so printf is better if you want to preserve. Which then are you referring to, it is on the line after the if statement just to be consistent with the original post?
    – Amos Baker
    Apr 6 at 16:04















up vote
0
down vote













It looks like you were eventually satisfied with the outcome of this question but I propose something different.



#!/bin/bash
LOG=/path/to/file.log
DEBUG=0 # 0 = True, 1 = False
OUTPUT=$(scp file1 host@remote 2>&1)

# do 'whatever' if scp command succeeds:
if [ $? -eq 0 ];
then
echo "Success"
elif [[ DEBUG -eq 0 ]]
# else log both stdout/stderr to $LOG file and user
# DEBUG - Use tee to display $LOG contents efficiently
printf "$OUTPUT" | tee $LOG
else
# Send output to $LOG
printf "$OUTPUT" >> $LOG
fi


Essentially capture STDIN/STDOUT in a variable no matter what, then if success do 'whatever' but if failure redirect STDIN/STDOUT to $LOG. Additionally with the $DEBUG flag you can tee the contents of $OUTPUT to the display and $LOG simultaneously.



Also for integer comparison you really should use -eq instead of = or ==






share|improve this answer






















  • Note that the value of $? at the point where you access it will be the return code of the assignment DEBUG=0. $? will be non-zero if that assignment fails (which is possible if DEBUG is a read-only variable). Also note that your calls to echo will remove any newlines from the value $OUTPUT, and that there is also a then missing.
    – Kusalananda
    Apr 6 at 14:49











  • Ah, yeah the $? is referencing the wrong thing, DEBUG was an afterthought but I'll fix it. echo does in fact remove the newlines so printf is better if you want to preserve. Which then are you referring to, it is on the line after the if statement just to be consistent with the original post?
    – Amos Baker
    Apr 6 at 16:04













up vote
0
down vote










up vote
0
down vote









It looks like you were eventually satisfied with the outcome of this question but I propose something different.



#!/bin/bash
LOG=/path/to/file.log
DEBUG=0 # 0 = True, 1 = False
OUTPUT=$(scp file1 host@remote 2>&1)

# do 'whatever' if scp command succeeds:
if [ $? -eq 0 ];
then
echo "Success"
elif [[ DEBUG -eq 0 ]]
# else log both stdout/stderr to $LOG file and user
# DEBUG - Use tee to display $LOG contents efficiently
printf "$OUTPUT" | tee $LOG
else
# Send output to $LOG
printf "$OUTPUT" >> $LOG
fi


Essentially capture STDIN/STDOUT in a variable no matter what, then if success do 'whatever' but if failure redirect STDIN/STDOUT to $LOG. Additionally with the $DEBUG flag you can tee the contents of $OUTPUT to the display and $LOG simultaneously.



Also for integer comparison you really should use -eq instead of = or ==






share|improve this answer














It looks like you were eventually satisfied with the outcome of this question but I propose something different.



#!/bin/bash
LOG=/path/to/file.log
DEBUG=0 # 0 = True, 1 = False
OUTPUT=$(scp file1 host@remote 2>&1)

# do 'whatever' if scp command succeeds:
if [ $? -eq 0 ];
then
echo "Success"
elif [[ DEBUG -eq 0 ]]
# else log both stdout/stderr to $LOG file and user
# DEBUG - Use tee to display $LOG contents efficiently
printf "$OUTPUT" | tee $LOG
else
# Send output to $LOG
printf "$OUTPUT" >> $LOG
fi


Essentially capture STDIN/STDOUT in a variable no matter what, then if success do 'whatever' but if failure redirect STDIN/STDOUT to $LOG. Additionally with the $DEBUG flag you can tee the contents of $OUTPUT to the display and $LOG simultaneously.



Also for integer comparison you really should use -eq instead of = or ==







share|improve this answer














share|improve this answer



share|improve this answer








edited Apr 6 at 16:08

























answered Apr 6 at 14:34









Amos Baker

11




11











  • Note that the value of $? at the point where you access it will be the return code of the assignment DEBUG=0. $? will be non-zero if that assignment fails (which is possible if DEBUG is a read-only variable). Also note that your calls to echo will remove any newlines from the value $OUTPUT, and that there is also a then missing.
    – Kusalananda
    Apr 6 at 14:49











  • Ah, yeah the $? is referencing the wrong thing, DEBUG was an afterthought but I'll fix it. echo does in fact remove the newlines so printf is better if you want to preserve. Which then are you referring to, it is on the line after the if statement just to be consistent with the original post?
    – Amos Baker
    Apr 6 at 16:04

















  • Note that the value of $? at the point where you access it will be the return code of the assignment DEBUG=0. $? will be non-zero if that assignment fails (which is possible if DEBUG is a read-only variable). Also note that your calls to echo will remove any newlines from the value $OUTPUT, and that there is also a then missing.
    – Kusalananda
    Apr 6 at 14:49











  • Ah, yeah the $? is referencing the wrong thing, DEBUG was an afterthought but I'll fix it. echo does in fact remove the newlines so printf is better if you want to preserve. Which then are you referring to, it is on the line after the if statement just to be consistent with the original post?
    – Amos Baker
    Apr 6 at 16:04
















Note that the value of $? at the point where you access it will be the return code of the assignment DEBUG=0. $? will be non-zero if that assignment fails (which is possible if DEBUG is a read-only variable). Also note that your calls to echo will remove any newlines from the value $OUTPUT, and that there is also a then missing.
– Kusalananda
Apr 6 at 14:49





Note that the value of $? at the point where you access it will be the return code of the assignment DEBUG=0. $? will be non-zero if that assignment fails (which is possible if DEBUG is a read-only variable). Also note that your calls to echo will remove any newlines from the value $OUTPUT, and that there is also a then missing.
– Kusalananda
Apr 6 at 14:49













Ah, yeah the $? is referencing the wrong thing, DEBUG was an afterthought but I'll fix it. echo does in fact remove the newlines so printf is better if you want to preserve. Which then are you referring to, it is on the line after the if statement just to be consistent with the original post?
– Amos Baker
Apr 6 at 16:04





Ah, yeah the $? is referencing the wrong thing, DEBUG was an afterthought but I'll fix it. echo does in fact remove the newlines so printf is better if you want to preserve. Which then are you referring to, it is on the line after the if statement just to be consistent with the original post?
– Amos Baker
Apr 6 at 16:04


















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f405445%2fredirect-stdout-and-or-stderr-to-path-in-variable%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

How to check contact read email or not when send email to Individual?

Bahrain

Postfix configuration issue with fips on centos 7; mailgun relay