I am executing a kubectl command in a bash script and storing the output in a variable. When the kubectl command executes successfully I am getting the correct output in the variable, but when it does not execute successfully the variable is empty and the error message is not available in the variable. I want the error values to be stores in the variable.
Example:
GET_PODS_COMMAND="$(kubectl get pods -n mlsh-$JOBNAMESPACE --selector app=$POD_SELECTOR --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')" #kubectl command. Please assume mlsh-$JOBNAMESPACE and $POD_SELECTOR have correct values
GET_PODS_COMMAND_OUT=$GET_PODS_COMMAND
echo $GET_PODS_COMMAND_OUT #Printing command result
When the command execution is successful I get the pod name in GET_PODS_COMMAND_OUT but when the command output is "No Resources Found" value for GET_PODS_COMMAND_OUT is blank.
I read that I have to redirect the stderr to stdout as stated in below articles:
Bash how do you capture stderr to a variable?
https://www.reddit.com/r/kubernetes/comments/98s8v6/why_cant_i_store_outputs_of_kubectl_commands_in_a/
Still struggling to understand how exactly to achieve this.
Here is what I have tried:
GET_PODS_COMMAND_OUT="$(GET_PODS_COMMAND 2>&1)" #gives the error: GET_PODS_COMMAND: command not found
New to linux so any help is appreciated. Thank you.
Related
I tried to check if Kubernetes cluster namespace exists and handle the case if it does not. I initialize my bash script with set -euo pipefail in order to handle errors.
The context is I need to implement the script when my_ns does not exist.
I stored the output of the kubectl get ns my_ns command (as it returns error message) into a bash variable but the script exits:
The point is I don't understand why when I use environment variable with export command it works:
I stored the output of the kubectl get ns my_ns command into a bash variable:
checknsoutput=$(kubectl get ns my_ns 2>&1)
I tried with export and it works
export checknsoutput=$(kubectl get ns my_ns 2>&1)
I enabled the "debug" mode thanks to the following command in order to have more verbosity:
set -x
This is the snippet of the logs for the script with the export command:
++ kubectl get ns toto
+ export 'checknsoutput=Error from server (NotFound): namespaces "toto" not found'
+ checknsoutput='Error from server (NotFound): namespaces "toto" not found'
+ echo 'RESULLT: Error from server (NotFound): namespaces "toto" not found'
This is the snippet of the logs for the script with a basic variable:
++ kubectl get ns toto
+ checknsoutput='Error from server (NotFound): namespaces "toto" not found'
If I correctly understand the kubectl get ns my_ns returned 1 and it catches by the script and exists before the initialization of the value checknsoutput.
I expect to understand why it does not work with variable whereas it does with export variable.
Thanks in advance for your help
export is a command with its own exit code. In general it exits 0 unless you tell it to export an invalid shell variable, so it will mask the exit code of the command substitution and prevent set -e from aborting the script.
If you want the script to exit on the command failure, you need to perform the assignment and export steps separately.
checknsoutput=$(kubectl get ns my_ns 2>&1)
export checknsoutput
See BashPitfalls 27.
I am running below command in openshift platform which produces some output
oc get pods
name status
job1 Running
job2 Completed
How to extract only status from the above result and store it in a variable using shell script.
ex : status=completed
How to extract only status from the above result and store it in a
variable using shell script.
ex : status=completed
Try status=$(oc get pods -o=custom-columns=STATUS:.status.phase --no-headers). You can echo $status and see the list of status saved in the environment variable.
If you add --output=json to your commands you can use JQ to select the status. I find bash scripts great for using commands but there are a lot of drawbacks when it comes to parsing output. With JSON you can regardless of the format select the correct key.
I want to assign a variable in shell script for the below aws command..
If the command is successful,I want to assign the output to S3_BUCKET_REGION.Eg: S3_BUCKET_REGION = us-east-1.
S3_BUCKET_REGION=$( aws s3api get-bucket-location --bucket ${TF_STATE_S3_BUCKET} | jq -r '.LocationConstraint // "us-east-1"' )
But if the bucket does not exist,the error for the above command is "An error occurred (NoSuchBucket) when calling the GetBucketLocation operation: The specified bucket does not exist"
I want to capture this error and echo it in the script.
So if the command runs successfully,I want to assign to a variable.If not ,I want to echo the error.How to do conditional statement for this?
Usually commands sends output to STDOUT and errors to STDERR.
$() grabs only STDOUT, so you should finish your command with redirection of STDERR to STDOUT
MYVAR=$( blablabla 2>&1 )
I know this has been asked many times, but I can find a suitable answer in my case.
I croned a backup script using rsync and would like to see all output, errors or not, from the all script commands. I must write the command inside the script itself, and do not want to see output in my shell.
I have been trying with no success. Below part of the script.
#!/bin/bash
.....
BKLOG=/mnt/backup_error_$now.txt
# Log everything to log file
# something like
exec 2>&1 | tee $BKLOG
# OR
exec &> $BKLOG
I have been adding at the script beginig all kinds of exec | tee $BKLOG with adding &>, 2>&1at various part of the command line, but all failed. I either get an empty log file or incomplete. I need to see on log file what rsync has done, and the error if script failed before syncing.
Thank you for help. My shell is zsh, so any solution in zsh is welcomed.
To redirect all the stdout/stderr to a file place this line on top of your script:
BKLOG=/mnt/backup_error_$now.txt
exec &> "$BKLOG"
I would like to pass parameters to a perl script using positional parameters inside a bash script "tablecheck.sh". I am using an alias "tablecheck" to call "tablecheck.sh".
#!/bin/bash
/scripts/tables.pl /var/lib/mysql/$1/ /var/mysql/$1/mysql.sock > /tmp/chktables_$1 2>&1 &
Perl script by itself works fine. But when I do "tablecheck MySQLinstance", $1 stays $1. It won't get replaced by the instance. So I get the output as follows:
Exit /scripts/tables.pl /var/lib/mysql/$1/ /var/mysql/$1/mysql.sock > /tmp/chktables_$1 2>&1 &
The job exits.
FYI: alias tablecheck='. pathtobashscript/tablecheck.sh'
I have a bunch of aliases in another bash script. Hence . command.
Could anyone help me... I have gone till the 3rd page of Google to find an answer. Tried so many things with no luck.
I am a noob. But may be it has something to do with it being a background job or $1 in a path... I don't understand why the $1 won't get replaced...
If I copy your exact set up (which I agree with other commenters, is some what unusual) then I believe I am getting the same error message
$ tablecheck foo
[1]+ Exit 127 /scripts/tables.pl /var/lib/mysql/$1/ /var/mysql/$1/mysql.sock > /tmp/chktables_$1 2>&1
In the /tmp/chktables_foo file that it makes there is an additional error message, in my case "bash: /scripts/tables.pl: No such file or directory"
I suspect permissions are wrong in your case