Backslashes are removed unless quoted in command line flags - string

I'm using the flag package to interpret flags entered at the command line.
I created a variable using
ptrString := flag.String("string", "", "A test string")
flat.Parse()
Then when I want to print it,
fmt.Println("You entered " + *ptrString)
If I enter something like -string=hello! as a command line argument, it prints "hello!"
If I enter something like -string=hello\Bob as a command line argument, it prints "helloBob"
Is there a recommended way to convert or interpret the flag argument to a string that doesn't remove the backslash? (This is being tested on Linux and OS X, if the shell is interfering...)

Characters that have special meaning in the shell need to be quoted or escaped. You can find complete list in the shell's man pages (under "Quoting" in man 1 bash).
In this case, you can either quote or escape the baskslash
-string=hello\\Bob
// or
-string='hello\Bob'

Related

Bash prompt variables does not work inside a bash function

I'm working on a prompt customization, but for some reason, when I use the \u, \h and \W variables as is it works perfectly, but when I put them inside a function, they are displayed as "\u" or "\W" instead of their values.
...
print_user()
{
echo -e "\001\u\002#\001\h\002"
}
print_dir()
{
echo -e "\001${YELLOW}\002\001\W\002\001${RESET_ATTR}\002"
}
PS1='[$(print_user) on $(print_dir)] $(get_git_repo) \001\n\002$(print_prompt) '
This displays as:
[\u#\h on \W]
>
If I move them outside of the function like so
PS1='[\[\u\]#\[\h\] \[${YELLOW}\]\[\w\]\[${RESET_ATTR}\]] $(get_git_repo) \[\n\]$(print_prompt)'
It works fine, and displays the current directory with the username and hostname:
[myusername#arch on ~]
>
Is this just how bash works? Is there a different way of doing it so it will work? Why is it that inside of a function it won't display the variables' values but outside of a function it does?
From the man page, under PROMPTING
Bash allows these prompt strings to be customized by inserting a number of
backslash-escaped special characters that are decoded as follows:
[...]
After the string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal, subject to the value of the
promptvars shell option (see the description of the shopt command under SHELL BUILTIN COMMANDS below).
By the time the shell expands $(print_user) to add \u to the string, it is too late to decode it, so the literal string \u remains in the prompt.
One alternative is to use PROMPT_COMMAND to execute a function that defines PS1 dynamically, just before it is displayed, instead of embedding command substitution in the value of PS1 itself.
make_prompt () {
PS1="[$(print_user) on $(print_dir)] $(get_git_repo)"
PS1+='\[\n\]'
PS1+="$(print_prompt) "
}
PROMPT_COMMAND=make_prompt
Now, print_user will have been called before the shell decodes the value of PS1, by which time all the prompt escapes will be present.

How do I pass ">>" or "<<" to my script without the terminal trying to interpret it as me either appending to something or getting stdin?

My python script can take a series of bitwise operators as one of its arguments. They all work fine except for "=<<" which is roll left, and "=>>" which is roll right. I run my script like ./script.py -b +4,-4,=>>10,=<<1, where anything after -b can be any combination of similar operations. As soon as the terminal sees "<<" though, it just drops the cursor to a new line after the command and asks for more input instead of running the script. When it sees ">>", my script doesn't process the arguments correctly. I know it's because bash uses these characters for a specific purpose, but I'd like to get around it while still using "=>>" and "=<<" in my arguments for my script. Is there any way to do it without enclosing the argument in quotation marks?
Thank you for your help.
You should enclose the parameters that contain special symbols into single quotation marks (here, echo represents your script):
> echo '+4,-4,=>>10,=<<1'
+4,-4,=>>10,=<<1
Alternatively, save the parameters to a file (say, params.txt) and read them from the file onto the command line using the backticks:
> echo `cat params.txt`
+4,-4,=>>10,=<<1
Lastly, you can escape some offending symbols:
> echo +4,-4,=\>\>10,=\<\<1
+4,-4,=>>10,=<<1

Common lisp: run shell command containing the string "\n"

I'm trying to run something that simplifies to
(trivial-shell:shell-command
(concatenate 'string "echo -e " "one" "\n" "two"))
And trying to get it to return something like
"one
two"
Whereas what it returns instead is
"onentwo
"
I'd be open to using something different from trivial-shell (I've tried inferior-shell, but it had the same problem)
Using SBCL 1.1.18 on 64-bit Gentoo Linux
The simplest way to output a newline is to have a newline character inside your string:
(print "one
two")
You can also coerce the newline character into a string:
(concatenate 'string "one" (string #\newline) "two")
You cannot use \n in a string to insert newlines: the backslash is only used to escape double-quotes inside strings (e.g. "\""). Necessarily, it is used to escape actual backslashes character too.
So if you want to print a backslash followed by n, you need to escape the backslash:
(print "\\n")
But then, why do you need 4 backslashes?
Because trivial-shell:shell-command invokes a shell, as given by *bourne-compatible-shell*, and gives it a command as a string. And so, your string might be subject to shell escaping rules too.
(trivial-shell:shell-command "echo -e one \\\\n two")
Knowing that, you might want to take into account the fact that bourne compatible shells have single-quotes, which do not require escaping characters inside of them. The following works as expected:
(trivial-shell:shell-command "echo 'one
two'")
Note that the default value for trivial-shell:*bourne-compatible-shell* is "/bin/sh", which as far as I know does not recognize the -e option for echo. You might already know this, but you might want to use a different shell. Here is a program that calls echo with newlines between arguments:
(defun echo-args (&rest args)
(let ((trivial-shell:*bourne-compatible-shell* #P"/bin/bash"))
(trivial-shell:shell-command
(format nil "echo -e '~{~A~^~%~}'" args))))
Solved it by using four backslashes instead of one.

Multiword string as a curl option using Bash

I want to get some data from a HTTP server. What it sends me depends on what I put in a POST request.
What I put in the INPUT_TEXT field is a sequence of words. When I run the following command, I get good looking output.
$ curl http://localhost:59125/process -d INPUT_TEXT="here are some words"
I want a bash script to take some string as a command line argument, and pass it appropriately to curl. The first thing I tried was to put the following in a script:
sentence=$1
command="curl http://localhost:59125/process -d INPUT_TEXT=\"${sentence}\""
$command
I then run the script like so:
$ ./script "here are some words"
But then I get a curl Couldn't resolve host error for each of "are", "some", and "words". It would seem that "here" got correctly treated as the INPUT_TEXT, but the rest of the words were then considered to be hosts, and not part of the option.
So I tried:
command=("curl" "http://localhost:59125/process" "-d" "INPUT_TEXT='$sentence'")
${command[#]}
I got the same output as the first script. I finally got what I wanted with:
result=$(curl http://localhost:59125/process -d INPUT_TEXT="${sentence}")
echo $result
I'm still unsure as to what the distinction is. In the first two cases, when I echoed out the contents of command, I get exactly what I input from the interactive Bash prompt, which had worked fine. What caused the difference?
The following will work:
command=("curl" "http://localhost:59125/process"
"-d" "INPUT_TEXT=$sentence")
"${command[#]}"
That has two changes from yours:
I removed the incorrect quotes around $sentence since you don't want to send quotes to the server (as far as I can see).
I put double-quotes around the use of "${command[#]}". Without the double quotes, the array's elements are concatenated with spaces between them and then the result is word-split. With double quotes, the individual array elements are used as individual words.
The second point is well-explained in the bash FAQ and a bunch of SO answers dealing with quotes.
The important thing to understand is that quotes only quote when a command is parsed. A quote which is a character in a variable is just a character; it is not reinterpreted when the value of the variable expanded. Whitespace in the variable is used for word-splitting if the variable expansion is unquoted; the fact that the whitespace was quoted in the the command which defined the variable is completely irrelevant. In this sense, bash is just the same as any other programming language.

Semicolon on command line in linux

i am running my application in linux by providing inputs as command line. My input field contain an argument which contains ";"(semicolon) internally.(For example:123;434;5464).
This will be parsed using UTF8String encode and send.
But when i am using like this, in initial itself i am getting,
bash: 434: command not found
bash: 5464: command not found
And when i capture traffic the output contains only 123 instead 123;434;5464
But if i give without semicolon (Ex:123:434:5464),not getting any problem output coming properly as 123:434:5464
Point me how to give command line input by using semicolon as to come output. Is there any particular syntax to use while doing with semicolon.
I am running like below
./runASR.sh -ip 10.78.242.4 -port 3868 -sce 10.78.241.206 -id 85;167838865;1385433280
where -id field contain that value with issue.
; is treated an end of command character. So 123;456;5464 to bash is in fact 3 commands. To pass such meta-characters escape it with escape character \.
./command 123\;456\;5464
Or Just quote it with single quote (double quote evaluates the inner string) (Thanks Triplee, I forgot to mention this)
./command '123;456;5464'

Resources