user578895
user578895

Reputation:

Bash: echo & copy result

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

Answers (2)

Benjamin W.
Benjamin W.

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

Will Barnwell
Will Barnwell

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

Related Questions