[PYTHON] It is said that Fabric cannot get the status code in the middle of the pipe in the shell script.

background

For example

$ true | false | true

Or

$ ls -S1 hoge* | haed -n1

Immediately after running a shell script that includes pipe processing like

$ echo $?

When checking the status code with a command such as, even if an error occurs in the first or intermediate process, only the last status code of the pipe can be obtained.

When you get the status code of the progress, you can get it by referring to the array $ {PIPESTATUS [@]} immediately after execution.

$ true | false | true
$ echo ${PIPESTATUS[@]}
0 1 0

For Fabric

Normally, in the case of Fabric, the return values of the run command and sudo command have properties such as .succeeded and .failed, so they are often referred to.

result = run("false", warn_only=True)
print result.succeeded

However, since there is no variable corresponding to $ {PIPESTATUS [@]}, the status code cannot be obtained in the middle.

problem

Consider an example like the shell script at the beginning.

@task
def return_test():
    #Show the largest file containing the string hoge in the current directory
    result = run("ls -S1 *hoge* | head -n1")
    print result.succeed
    print result

At this time, if there is no file / directory containing hoge in the current directory, .succeeded will only return the result of run (since head can be executed, this is True), As the content, the error display (standard error output) is returned as it is.

[192.168.0.1] Executing task 'return_test'
[192.168.0.1] run: ls -S1 *hoge* | head -n1
[192.168.0.1] out: ls: cannot access *hoge*: No such file or directory
[192.168.0.1] out:

True
ls: cannot access *hoge*: No such file or directory

Done.
Disconnecting from 192.168.0.1... done.

The information I originally wanted wasn't returned, and it's unpleasant, but in this example, it may happen that the directory name is such a directory name.

Solution (Conclusion)

Let's make the tea muddy.

@task
def return_test():
    result = run("ls -S1 *hoge* 2> /dev/null | head -n1")
    print result
[192.168.0.1] Executing task 'return_test'
[192.168.0.1] run: ls -S1 *hoge* 2> /dev/null | head -n1


Done.
Disconnecting from 192.168.0.1... done.

Recommended Posts

It is said that Fabric cannot get the status code in the middle of the pipe in the shell script.
Get the return code of the Python script from bat
[OCI] Python script to get the IP address of a compute instance in Cloud Shell
[Note] A shell script that checks the CPU usage of a specific process in a while loop.
Code that sets the default value in case of AttributeError
Memo of the program to get the date in two digits with javascript, Ruby, Python, shell script
Process the contents of the file in order with a shell script
Shell script (Linux, macOS) that outputs the date of the last week
Get the script path in Python
Find out the name of the method that called it from the method that is python
Get the return value of an external shell script (ls) with python3
Get the value of the middle layer of NN
[Python] Get the character code of the file
Get the EDINET code list in Python
It seems that the version of pyflakes is not the latest when flake8 is installed
In Python, change the behavior of the method depending on how it is called
Correspondence of the event that the result of form.is_valid () is always False in Django2 system
Hackathon's experience that it is most important to understand the feelings of the organizer