0

I'm working on wsl bash and I have the following function defined in my ~/.bashrc file:

function clip { /mnt/c/Windows/System32/clip.exe "${@%\n}"; }

However this does not remove the trailing \n from the arugument. How can I improve this to meet my specific needs?

Many thanks

EDIT: With the help of Kamil's answer, I was able to figure out what was actually going on. turns out that the spawned subprocess (cmd.exe) is adding the carriage return which is being inserted into clip.exe (because I was using pipes. ex. pwd | clip).

I was able to get the desired result with the following:

function clip { /mnt/c/Windows/System32/WindowsPowershell/v1.0/powershell.exe Set-Clipboard "${@:-$(cat)}"; }

It's a bit slow as it relies on

  • powershell
  • cat (external binary which should be replaced with read builtin)

But not a problem for my needs :)

0

1 Answer 1

3

"${@%\n}" removes a trailing n. "${@%\\n}" would remove trailing \n (literal string, not a newline).

To remove a newline character you need to pass a newline character. In Bash this syntax should work:

"${@%$'\n'}"

where $'\n' is responsible for generating an actual newline character. A literal newline will work as well:

"${@%
}"

Notes:

  • The solution removes trailing newline from each argument, not only from the last (because this is how $@ works).
  • In Linux its unusual to have a trailing newline in a command line argument. I don't know WSL, I don't know your usage case; I hope you know what you want*.

Example:

$ set a $'b\n' c
$ printf '<%s>\n' "$@"
<a>
<b
>
<c>
$ printf '<%s>\n' "${@%$'\n'}"
<a>
<b>
<c>
$ printf '<%s>\n' "${@%
}"
<a>
<b>
<c>


* If "removing the trailing \n from the argument" is not what you want, then maybe you call the function in a (sourced?) script and the script suffers from DOS line ending(s). Check this question.

4
  • 1
    If Windows data is involved, do not overlook the possibility that \r is also in the mix. Commented May 9, 2020 at 9:16
  • @Paul_Pedant Windows data will not be involved (as clip is a windows executable that copies the given argument to the clipboard). Just WSL or bash > clipboard. It will always be a '\n'.
    – tinnick
    Commented May 9, 2020 at 10:43
  • @KamilMaciorowski Also, turns out that clip.exe appends a carriage return. Nothing you can do from WSL side. Thank you though!
    – tinnick
    Commented May 9, 2020 at 11:04
  • @tinnick If you need to remove a carriage return instead of a newline, use "${@%$'\r'}". If you need to remove a CR-LF pair, it's "${@%$'\r\n'}" Commented May 9, 2020 at 19:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .