0
Are the only options for bash command expansion:
- unquoted
$(..)
whose output is always parsed with dumb string splitting, or - quoted
"$(..)"
whose output is always passed along as a unit?
I'm trying to replicate in bash a fish shell function I created for use on Mac OS. My fish function selection
https://superuser.com/a/1165855 takes the selection in the frontmost window and outputs the paths for use in command substitution like ls -l (selection)
. I was hoping to achieve the same thing in bash perhaps as ls -l $(selection)
.
I thought it was a matter of quoting and so tried passing linefeed-delimited paths to bash's printf "%q "
. However I found that no matter what quoting I wrapped the command substitution output in, it was getting divided at whitespace.
Simplified example:
$ touch file\ a file\ b
$ ls $( echo "file\ a file\ b" ) # want expansion equiv to: ls 'file a' 'file b'
ls: a: No such file or directory
ls: b: No such file or directory
ls: file\: No such file or directory
ls: file\: No such file or directory
It wouldn't be the end of the world if I had to use quoted command substitution like ls -l "$(selection)"
but doing that the command's output never gets split, nevermind observing my careful quoting. Is the old backtick syntax any different?
Funny, bash, you've got a lot of features. Has nobody though to allow cmda $(cmdb-that-generates-parameters-for-cmda)
? Or does a bash user just avoid any spaces or symbols in filenames (like an animal) to make everything easy? Thanks for any answers.
change from "${i}.file" to "${i} x.file" ... what were you saying about being ok to use spaces? ;^) – Pierre Houston – 2018-08-31T21:18:44.100
And I'm looking to do something like this as a convenience from the command line, not from a script, so boilerplate like setting IFS etc is not appropriate. But thanks anyway, especially for direct answers to my specific questions – Pierre Houston – 2018-08-31T21:26:05.503
@PierreHouston Bug fixed :))) – Alex – 2018-08-31T21:26:13.610
@PierreHouston For command line operations (without making script) use variant#2, just separate commands with
;
character – Alex – 2018-08-31T21:28:48.800Nice fast bug fix :thumbsup:. I don't see how #2 helps me at all. I (almost) literally want to type at a bash prompt:
cmda $(cmdb-that-generates-parameters-for-cmda)
, a more literal example:transcode $(selection)
. It seems not possible, I'm going to just start using fish-shell on my work Macs. – Pierre Houston – 2018-08-31T21:33:46.600@PierreHouston
transcode "$(for i in '1 x.file' '2 x.file';do echo "${i}";done)"
That what I meant how to employ variant#2, list your files in place ofN x.file
but make sure you enclosed it with single quotes. You can insert your selection between in and first;
as many files as you need separated by space. – Alex – 2018-09-01T12:47:42.643Thanks @Alex but this is not in a script, this is me typing a command at the prompt and I'm looking for a convenience :^) If I have to type
transcode "$(for i in ... whatever
then fail because the syntax isn't convenient. If I have to type the names of the files, then fail because the point is to have that filled in for me. I very literally only want to typetranscode "$(selection)"
and have theselection
function or script find the files I want (this part I can do) and output something that bash will accept as paths that can have inconvenient spaces or symbols (this bash cannot do). – Pierre Houston – 2018-09-04T22:36:42.433@PierreHouston When you typing manually filenames that includes space in command line, all you have to do is to enclose those filenames in single quotes. As about populating filenames from function or script
selection
, - could you add some example of such function or script to your question, Im pretty sure we would find some solution, usually it is a matter of adding double quoiting like"'some file'"
in those external scripts or functions that generates filenames. – Alex – 2018-09-05T19:30:40.673Thanks for your continued interest Alex :^) If its a matter of quoting then in my original "file a" "file b" example with
transcode $( echo "X" )
, one could come up with some X that would end up withtranscode
getting the two parameters "file a" and "file b". It seems however that output from
$( )is not fed back into bash's quote parsing but instead split at spaces. If X is
'some file'then
transcodegets parameters
'someand
file'`. I should've spoken to your prev example more, I don't think "$( for i.. echo "${i} – Pierre Houston – 2018-09-06T17:58:28.073(forgive the incomplete edit in the previous comment) The suggestion in your previous comment,
transcode "$( for i.. )"
, would demonstrate the 2nd option bash has, quoted"$( .. )"
. It seems that any output from that is passed totranscode
as one parameter. If this is wrong, then one should be able to make a counter-example in the formtranscode "$( echo X )"
for some X, right? So sorry if my original Q was unclear, restating: was trying to find an X so that eithertranscode $( echo X )
ortranscode "$( echo X )"
will end up withtranscode
getting the parametersfile a
file b
– Pierre Houston – 2018-09-06T18:14:27.307@PierreHouston Sorry with delay answer, got a little busy last days. I added one more solution to my answer(in the end), I guess it is exactly what you are looking for. If you need some assistance to create external script that would feed correctly
_tr
function, then add to your question external script that you using to form list of files that includes space(s) in filenames, so we would try to correct it. – Alex – 2018-09-08T17:47:00.537