How to Include a Pipe | in My Linux Find -Exec Command

Using pipes with find command in linux

You could just use the verbose flag on rm and it will tell you what it's deleting

find ~/ -name "~*" | sort -n | head -5 |  xargs rm -v

Use man rm to see the docs

-v, --verbose

explain what is being done

Pipe Find command stderr to a command

Pipe stderr and stdout simultaneously - idea taken from this post:

(find /boot | sed s'/^/STDOUT:/' ) 3>&1 1>&2 2>&3 | sed 's/^/STDERR:/'

Sample output:

STDOUT:/boot/grub/usb_keyboard.mod
STDERR:find: `/boot/lost+found': Brak dostępu

Bash redirections like 3>&1 1>&2 2>&3 swaps stderr and stdout.

I would modify your sample script to look like this:

#!/bin/bash
ErrorFile="error.log"
(find ./subdirectory -type f 3>&1 1>&2 2>&3 | sed "s#^#${PWD}: #" >> $ErrorFile) 3>&1 1>&2 2>&3 | while read line; do
field1=$(echo "$line" | cut -d / -f2)
...
done

Notice that I swapped stdout & stderr twice.

Small additional comment - look at -printf option in find manual page. It might be useful to you.

Linux cli pipe output of command into another command

The bash builtin command mapfile may be what you're looking for. It reads the lines of output into an array.

mapfile -t files < <(find . -name *.txt)

The redirection from a process substitution is required to avoid subshells.

Then

  • the first file is in "${files[0]}"
  • the last file is in "${files[-1]}"
  • all the files are "${files[@]}"

Inspect the array with declare -p files

Unix pipe into ls

To do that you need xargs:

which studio | xargs ls -l

From man xargs:

xargs - build and execute command lines from standard input

To fully understand how pipes work, you can read What is a simple explanation for how pipes work in BASH?:

A Unix pipe connects the STDOUT (standard output) file descriptor of
the first process to the STDIN (standard input) of the second. What
happens then is that when the first process writes to its STDOUT, that
output can be immediately read (from STDIN) by the second process.

bash - how to pipe result from the which command to cd

You use pipe in cases where the command expects parameters from the standard input. ( More on this ).

With cd command that is not the case. The directory is the command argument. In such case, you can use command substitution. Use backticks or $(...) to evaluate the command, store it into variable..

path=`which oracle`
echo $path # just for debug
cd $path

although it can be done in a much simpler way:

cd `which oracle` 

or if your path has special characters

cd "`which oracle`"

or

cd $(which oracle)

which is equivalent to backtick notation, but is recommended (backticks can be confused with apostrophes)

.. but it looks like you want:

cd $(dirname $(which oracle))

(which shows you that you can use nesting easily)

$(...) (as well as backticks) work also in double-quoted strings, which helps when the result may eventually contain spaces..

cd "$(dirname "$(which oracle)")"

(Note that both outputs require a set of double quotes.)

How can I pipe output, from a command in an if statement, to a function?

The Print function doesn't read standard input so there's no point piping data to it. One possible way to do what you want with the current implementation of Print is:

if ! occ_output=$(sudo -u "$web_user" "$nextcloud_dir/occ" files:scan --all 2>&1); then
Print "Error: Failed to scan files. Are you in maintenance mode?"
fi

Print "'occ' output: $occ_output"

Since there is only one line in the body of the if statement you could use || instead:

occ_output=$(sudo -u "$web_user" "$nextcloud_dir/occ" files:scan --all 2>&1) \
|| Print "Error: Failed to scan files. Are you in maintenance mode?"

Print "'occ' output: $occ_output"

The 2>&1 causes both standard output and error output of occ to be captured to occ_output.

Note that the body of the Print function could be simplified to:

[[ $quiet_mode == No ]] && printf '%s\n' "$1"
(( logging )) && printf '%s\n' "$1" >> "$log_file"

See the accepted, and excellent, answer to Why is printf better than echo? for an explanation of why I replaced echo "$1" with printf '%s\n' "$1".

An error occurred while processing STDERR using the pipe

The issue here is "multiple redirect".

The reason this can not be reproduced on Ubuntu, is because Ubuntu (like many Debian based Linux distros) uses Ash or Bash shell by default, while recent MacOS version switched to using ZSH.

ZSH on Ubuntu will give similar result to what you are getting.

Apparently, using both redirect > and pipe | causes ZSH to split you stderr similar to tee command.

This post shows a solution to the problem:
https://unix.stackexchange.com/questions/265061/how-can-i-pipe-only-stderr-in-zsh

Specifically, you need to close stdout before redirecting it to /dev/null to prevent the split:

cat test foo 2>&1 >&- > /dev/null | cut -d ':' -f 3

This works with ZSH on Ubuntu, and should work on Mac OS.

If it does not, check the linked post for enabling mult_ios option in your shell.



Related Topics



Leave a reply



Submit