Timeline for How can we run a command stored in a variable?
Current License: CC BY-SA 4.0
43 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Nov 7, 2024 at 14:44 | comment | added | Steen Schütt | @ilkkachu Well TIL... Thank you. I had given up on it, but that just works. I guess I never realized that it didn't work normally either. | |
| Nov 7, 2024 at 11:41 | comment | added | ilkkachu |
@SteenSchütt, looks like you have to leave the / unquoted too for the shell to recognize the tilde expansion. a=( ls -l ~/"foo bar" ) works fine. As for your function, I couldn't say, maybe post a question on the site.
|
|
| Nov 7, 2024 at 11:36 | comment | added | Steen Schütt | ^ and given that I want to run the remainder of positional arguments as a command within my function, I think I have come to the conclusion that it simply cannot be done in a way that supports all edge cases. | |
| Nov 7, 2024 at 11:29 | comment | added | Steen Schütt |
Unfortunately the array expansion doesn't work for commands with partially quoted strings that should be expanded by bash. touch ~/touch; mycmd=(ls -l ~"/touch"); "${mycmd[@]}" will run ls on the literal path "~/touch".
|
|
| Jul 25, 2023 at 11:52 | comment | added | ilkkachu |
If you have an array and want to print it with proper quoting, you could try echo "${tmptest[@]@Q}", which should at least do something like that. Here, it prints 'mkdir' 'a; echo c', where quoting the mkdir is of course unnecessary, but whatever. (As far as I understand, the output of @Q should be usable as input to Bash, but I can't think of all the details right now, so I'm not exactly sure if there's still some gotcha. And yes, it's Bash only, zsh has better ways for the same.)
|
|
| Jul 25, 2023 at 11:50 | comment | added | ilkkachu |
@Summer-Sky, yes, of course. The point of storing the command as an array is to AVOID a round-trip via a string, and instead create it in the format it actually gets used as in the end: as an array of multiple separate strings. Also echo by itself is not really good at printing things unambiguously, it loses the difference between separate arguments and a single argument with a space in it.
|
|
| Jul 25, 2023 at 9:43 | comment | added | Summer-Sky |
and yea i am well aware it isn't the OPs request. I usually use SO only as a notepad for future-me, as in this case. I will know in the future to use the eval option ¯\_(ツ)_/¯,
|
|
| Jul 25, 2023 at 9:37 | comment | added | Summer-Sky |
it was a fidelity issue: here an example tmptest=(mkdir "a; echo c"); echo "${tmptest[@]}" ; "${tmptest[@]}" after that use the echoed command (ctrl+c ctrl+v) and spot the difference ... try again with escaped string and eval .. the point is to have a command that you can print out and that will be identical to what was executed
|
|
| Jul 24, 2023 at 12:03 | comment | added | ilkkachu | @Summer-Sky, well, if you refuse to show your code, no-one can help you find out why it doesn't do what it should and you won't learn how to do it properly. Have a nice day. | |
| Jul 24, 2023 at 11:24 | comment | added | Summer-Sky | i tired it with echo. | |
| Jul 23, 2023 at 17:55 | comment | added | ilkkachu | @Summer-Sky, it'd help if you could show the actual code you tried. Maybe post it in a new question. | |
| Jul 23, 2023 at 11:30 | comment | added | Summer-Sky | somehow the quotation marks in the array are not repected. i used eval , which works! | |
| Feb 9, 2023 at 20:49 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 912 characters in body
|
| Feb 7, 2023 at 18:09 | comment | added | ilkkachu |
@jtimz, the correct syntax for storing the command name and args in an array, is to take the syntax you'd use to run the command, exactly, and slap the parentheses and assignment around it. In that case, it's probably cmd=(find . \( -name "*.txt.gz" -o -name "*.sh" \) ). The way you showed it there, that "\( -name ... \)" is a single quoted string, one that has hard double-quotes it in, and that doesn't match any of the find expressions, so it's taken as a filename. (I'm not sure why the output has doubled backslashes.)
|
|
| Feb 7, 2023 at 16:22 | comment | added | jtimz |
Fantastic answer @ilkkachu, I would love to use the arrays in my case, however I am not able to make it work during expansion when the string has to escape, for example - suppose we have the following code: cmd=("find" "." "\( -name \"*.txt.gz\" -o -name \"*.sh\" \)"); echo "${cmd[*]}"; "${cmd[@]}". This fails as it is expanded with double quotes with the error find: ‘\\( -name "*.txt.gz" -o -name "*.sh" \\)’: No such file or directory - do you know how we are able to fix this? eval works without issues, i.e. eval "${cmd[*]}" instead of "${cmd[@]}".
|
|
| Jan 6, 2023 at 14:22 | comment | added | abc | how to up vote 2 times? )) used function approach | |
| Nov 2, 2022 at 18:09 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 238 characters in body
|
| Oct 25, 2022 at 2:25 | comment | added | Fjor | Thanks for the clarification, @ilkkachu, I thought it was some new command unknown to me (or from some shell I don't grok), related to array manipulation. | |
| Oct 23, 2022 at 19:15 | comment | added | ilkkachu |
@Fjor, you wouldn't, since there isn't such a command. That was supposed to be a generic placeholder for the command name, since it's not really relevant which command it is. Perhaps the choice of name used was a bit too cheesy and confusing, so sorry about that. (edited to call it somecommand instead and clarify the matter a bit.)
|
|
| Oct 23, 2022 at 19:12 | history | edited | ilkkachu | CC BY-SA 4.0 |
edited body
|
| Oct 23, 2022 at 19:06 | history | edited | ilkkachu | CC BY-SA 4.0 |
edited body
|
| Oct 23, 2022 at 6:14 | comment | added | Fjor |
@ilkkachu, I can't find references to the command transmutate you used in some examples. Could you please point me to some documentation?
|
|
| Sep 7, 2022 at 14:59 | comment | added | ilkkachu | @QuartzCristal, well, yeah, it's not word splitting per se as the simplest cases can work with the help of word splitting. But the fact that word splitting is simple and doesn't work in the complex cases even if people might expect it to help them is part of the matter. Edited. | |
| Sep 7, 2022 at 14:57 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 89 characters in body
|
| Sep 7, 2022 at 12:05 | history | edited | terdon♦ | CC BY-SA 4.0 |
added 1 character in body
|
| Sep 7, 2022 at 6:23 | comment | added | QuartzCristal | No, it is wrong to say that "The reason you face those problems is word splitting". That is simply: Not true. | |
| Jul 22, 2022 at 21:40 | comment | added | paul garrett | "... useful but dangerous..." Forsooth. :) | |
| Dec 6, 2021 at 11:15 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 795 characters in body
|
| Oct 28, 2021 at 12:40 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 287 characters in body
|
| Sep 20, 2021 at 20:47 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 507 characters in body
|
| Apr 18, 2021 at 10:21 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 1786 characters in body
|
| Oct 27, 2020 at 12:21 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 67 characters in body
|
| Jun 10, 2020 at 9:31 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 153 characters in body
|
| Oct 11, 2019 at 20:19 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 421 characters in body
|
| May 6, 2019 at 7:01 | history | edited | Kusalananda♦ | CC BY-SA 4.0 |
Add code examples using "$@"
|
| Nov 14, 2018 at 10:11 | history | edited | Stéphane Chazelas | CC BY-SA 4.0 |
added 4 characters in body
|
| May 23, 2018 at 2:25 | comment | added | Hopping Bunny |
Not directly related, but have you hard-coded the directory? In that case, you might want to look at alias. Something like: $ alias abc='ls -l "/tmp/test/my dir"'
|
|
| May 20, 2018 at 23:01 | vote | accept | Tim | ||
| May 20, 2018 at 19:39 | comment | added | phemmer |
you can get around the eval quoting thing by doing cmd="ls -l $(printf "%q" "$filename")". not pretty, but if the user is dead set on using an eval, it helps. It's also very useful for sending the command though similar things, such as ssh foohost "ls -l $(printf "%q" "$filename")", or in the sprit of this question: ssh foohost "$cmd".
|
|
| May 20, 2018 at 13:51 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 1598 characters in body
|
| May 20, 2018 at 13:20 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 1542 characters in body
|
| May 20, 2018 at 13:10 | history | edited | ilkkachu | CC BY-SA 4.0 |
added 1542 characters in body
|
| May 20, 2018 at 12:58 | history | answered | ilkkachu | CC BY-SA 4.0 |