Re: Feature Request: Custom delimeter for single quotes
On 1.11. 06:54, Patrick Blesi wrote: I'm looking for a hybrid between single quotes and a here doc or here string. The main use case is for accepting arbitrary user-specified text. Do your users enter the text by directly editing the script? Would it make more sense to use e.g. 'read' to read the input directly from the user? input="" nl=' ' echo "Enter text, end with ^D:" while IFS= read -r line; do input="$input$line$nl" done printf "You entered:\n---\n%s---\n" "$input" or to just have the text in a separate file (not the script) and read it from there? input=$(< inputfile) That way, the text appears in a variable, and you don't need to care about quotes inside it. (You could also read from stdin with just input=$(cat) instead of the while read loop but that feels a bit odd to me for some reason.) I would like to wrap this text in single quotes so as to prevent any variable expansion or interpretation of the text of any kind. Additionally, I would like to allow the users to include single quotes in their text without requiring that they escape these quotes. Something akin to the following would alleviate the need to communicate that users must escape single quotes, but also provide the same literal string behavior of single quotes. presuming the arbitrarily substituted text is: echo 'this command is specified by the user' Then a syntax for this single quote heredoc behavior could be like: $ sh -c <<^MAGIC_WORD echo 'this command is specified by the user' MAGIC_WORD Everything within the MAGIC_WORD declarations would not have command substitution, variable expansion, etc, but would be treated as if it were wrapped in single quotes with the exception that single quotes between the MAGIC_WORDs need not be escaped. Pardon my naïveté, does any such feature exist or are there good ways to accomplish this? If not, is this something that could feasibly be implemented? Would it be desirable? Thanks, Patrick -- Ilkka Virta / itvi...@iki.fi
Re: Feature Request: Custom delimeter for single quotes
The actual use case is taking a command from a Ruby script: https://github.com/braintree/runbook/blob/4a0f0770a8a2a7be135cf13ee435d981b5975a06/lib/runbook/helpers/tmux_helper.rb#L23 `tmux send-keys -t #{target} #{_pager_escape_sequence} '#{command}' C-m` The user specifies the command they want to run as a Ruby string and it gets interpolated into the above string and then executed (The backticks in Ruby invoke the command in a subprocess and return the output as a string, #{} is string interpolation). As you can see, if the user-specified command has a single quote, it will break this command unless escaped. I think doing something like this should serve my needs: ` command=$(cat <<'MAGIC_WORD' #{command} MAGIC_WORD ) tmux send-keys -t #{target} #{_pager_escape_sequence} "$command" C-m ` So that no single quote escaping is required. The non-valid input for the command would be MAGIC_WORD. Do you know if this command is POSIX compliant/supported by a large number of shells? Is is supported by the bourne shell? On Fri, Nov 1, 2019 at 3:37 AM Ilkka Virta wrote: > On 1.11. 06:54, Patrick Blesi wrote: > > I'm looking for a hybrid between single quotes and a here doc or here > > string. > > > > The main use case is for accepting arbitrary user-specified text. > > Do your users enter the text by directly editing the script? > Would it make more sense to use e.g. 'read' to read the input directly > from the user? > > input="" > nl=' > ' > echo "Enter text, end with ^D:" > while IFS= read -r line; do > input="$input$line$nl" > done > > printf "You entered:\n---\n%s---\n" "$input" > > > or to just have the text in a separate file (not the script) and read it > from there? > > input=$(< inputfile) > > > That way, the text appears in a variable, and you don't need to care > about quotes inside it. > > > (You could also read from stdin with just input=$(cat) instead of the > while read loop but that feels a bit odd to me for some reason.) > > > I would > > like to wrap this text in single quotes so as to prevent any variable > > expansion or interpretation of the text of any kind. Additionally, I > would > > like to allow the users to include single quotes in their text without > > requiring that they escape these quotes. > > > > Something akin to the following would alleviate the need to communicate > > that users must escape single quotes, but also provide the same literal > > string behavior of single quotes. > > > > presuming the arbitrarily substituted text is: > > > > echo 'this command is specified by the user' > > > > Then a syntax for this single quote heredoc behavior could be like: > > > > $ sh -c <<^MAGIC_WORD echo 'this command is specified by the user' > > MAGIC_WORD > > > > Everything within the MAGIC_WORD declarations would not have command > > substitution, variable expansion, etc, but would be treated as if it were > > wrapped in single quotes with the exception that single quotes between > the > > MAGIC_WORDs need not be escaped. > > > > Pardon my naïveté, does any such feature exist or are there good ways to > > accomplish this? If not, is this something that could feasibly be > > implemented? Would it be desirable? > > > > Thanks, > > > > Patrick > > > > > -- > Ilkka Virta / itvi...@iki.fi >
Re: Feature Request: Custom delimeter for single quotes
On 11/1/19 3:57 PM, Patrick Blesi wrote: > The actual use case is taking a command from a Ruby script: > > https://github.com/braintree/runbook/blob/4a0f0770a8a2a7be135cf13ee435d981b5975a06/lib/runbook/helpers/tmux_helper.rb#L23 > > `tmux send-keys -t #{target} #{_pager_escape_sequence} '#{command}' C-m` > > The user specifies the command they want to run as a Ruby string and it > gets interpolated into the above string and then executed (The backticks in > Ruby invoke the command in a subprocess and return the output as a string, > #{} is string interpolation). As you can see, if the user-specified command > has a single quote, it will break this command unless escaped. I don't know about ruby. I know that in, say, python, the subprocess module can take an array with a command executable and its arguments, and execute it using the exec() family of functions. You can optionally request that the subprocess module do its execution via a shell, just like system() does, but it's generally not exactly recommended. Have you considered rewriting your ruby program to not use vulnerable methods of executing subprocesses? Given that ruby is, presumably, a powerful programming language, I don't understand why you would want to write a program that now uses *two* programming languages: - ruby - /bin/sh when you could do all your work in ruby. If you absolutely require using shell syntax in your subprocess for inexplicable reasons, you can use the shell syntax embedded within this pseudocode, which would be executed using the exec() family of functions: {'sh', '-c', 'do_things "$1"', '_', 'argv_containing_user_input'} given sh is being passed an argument without introducing a shell, and that argument is assigned to the shell variable $1, that argument can be defined and passed to exec() containing anything which ruby wants to put there. Safely. > I think doing something like this should serve my needs: > > ` > command=$(cat <<'MAGIC_WORD' > #{command} > MAGIC_WORD > ) > tmux send-keys -t #{target} #{_pager_escape_sequence} "$command" C-m > ` > So that no single quote escaping is required. The non-valid input for the > command would be MAGIC_WORD. Do you know if this command is POSIX > compliant/supported by a large number of shells? Is is supported by the > bourne shell? Is what command POSIX compliant? - The one you're proposing be added, right now, to bash and bash alone? - tmux? - cat with quoted delimiter tokens? -- Eli Schwartz Arch Linux Bug Wrangler and Trusted User signature.asc Description: OpenPGP digital signature
Re: Feature Request: Custom delimeter for single quotes
On Nov 01 2019, Patrick Blesi wrote: > The actual use case is taking a command from a Ruby script: > > https://github.com/braintree/runbook/blob/4a0f0770a8a2a7be135cf13ee435d981b5975a06/lib/runbook/helpers/tmux_helper.rb#L23 > > `tmux send-keys -t #{target} #{_pager_escape_sequence} '#{command}' C-m` > > The user specifies the command they want to run as a Ruby string and it > gets interpolated into the above string and then executed (The backticks in > Ruby invoke the command in a subprocess and return the output as a string, > #{} is string interpolation). As you can see, if the user-specified command > has a single quote, it will break this command unless escaped. Just shell-quote the characters in the interpolated string, as you need to do anyway for the other interpolated strings. Not doing this would be a security bug waiting to happen. Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different."
Running 32 bit program on 64 bit system makes bash etc. look bad
$ mapping/taipower/pole2tm bash: mapping/taipower/pole2tm: No such file or directory Must be a bash bug! Proof: $ ls -l mapping/taipower/pole2tm -rwxr-xr-x 1 jidanni jidanni 11290 2012-06-19 mapping/taipower/pole2tm But wait, $ strace mapping/taipower/pole2tm execve("mapping/taipower/pole2tm", ["mapping/taipower/pole2tm"], 0x7ffd53416200 /* 58 vars */) = -1 ENOENT (No such file or directory) strace: exec: No such file or directory +++ exited with 1 +++ Must also be a strace bug... Ah, $ file mapping/taipower/pole2tm mapping/taipower/pole2tm: ELF 32-bit LSB executable... but we are running it on $ arch x86_64 Anyway, perhaps somebody could submit a kernel bug, telling them to somehow make bash, etc. look less bad, by a clearer error message, as I suppose bash cannot always catch such cases, to make a better error message. In fact maybe bash could catch it (expensive?): First "stat" the file. If it doesn't exist bash should make its own message bash: /tmp/abce: No such file or directory If it does, then bash should be prepared to catch the kernel's message (which is referring to a *different* file, which yes, actually does not exist.) Whereupon bash could make a better error message.