Reputation:
I'm just trying to make a function that echos and copies whatever is passed to it to the clipboard:
function c() {
echo "$@"
pbcopy "$@"
}
c 123
echos properly but then just waits for input
pwd | c
copies to the clipboard but doesn't echo
Upvotes: 0
Views: 2173
Reputation: 52451
Here's a function that checks if arguments are supplied and reads input from stdin if not:
c() {
if (( $# )); then
printf '%s\n' "$*"
printf '%s' "$*" | pbcopy
else
tee >(pbcopy)
fi
return 0
}
The somewhat cumbersome double printf
is there to avoid getting the linebreak into the clipboard. For the case of reading from stdin, however, you will have that linebreak in the clipboard if you feed it one:
$ c blah
blah
$ pbpaste
blah$ echo blah | c
blah
$ pbpaste
blah
$ printf blah | c
blah$ pbpaste
blah$
where the $
is the command prompt, directly behind the output if the output doesn't contain a newline. This might or might not be what you want: I find that I expect the newline to not be in the string if I supply the string as an argument, and if I read from standard input, I'll leave the newline there if there is one.
Upvotes: 1
Reputation: 4089
Based on https://unix.stackexchange.com/questions/28503/how-can-i-send-stdout-to-multiple-commands
function c() {
echo "$@" | tee >(pbcopy)
}
Should do the trick. I tested this in zsh, but i expect this will work in bash as well.
As that other guy pointed out in the comments, pbcopy reads from stdin, it doesn't copy arguments, which is why your pipe vs argument test had the results it did.
tee
splits the pipe, sending stdout to a file, but also leaves it in stdout.
>(command)
opens a file descriptor which pipes to command
Combining the two allows us to echo the arguments back to stdout while also piping them to pbcopy
A caveat to this solution is that the clipboard will contain a newline, as echo by default adds a newline to output. This could be prevented by passing the -n
flag to echo.
Upvotes: 2