How can I preserve command line spaces in a linux application?
#!/bin/bash
export LD_LIBRARY_PATH=./libs:$LD_LIBRARY_PATH
exec ./TheBinary "$@"
I have no real idea whether /bin/sh supports that syntax
Bash: preserve string with spaces input on command line?
The main thing to worry about is that when you refer to a variable without enclosing it in double-quotes, the shell does word splitting (splits it into multiple words wherever there's a space or other whitespace character), as well as wildcard expansion. Solution: use double-quotes whenever you refer to a variable (e.g. echo "$input"
).
Second, read
will trim leading and trailing whitespace (i.e. spaces at the beginning and/or end of the input). If you care about this, use IFS= read
(this essentially wipes out its definition of whitespace, so nothing gets trimmed). You might also want to use read
's -r
("raw") option, so it doesn't try to interpret backslash at the end of a line as a continuation character.
Finally, I'd recommend using read
's -p
option to supply the prompt (instead of echo -n
).
With all of these changes, here's what your script looks like:
IFS= read -r -p "Enter description: " input
echo "$input"
How to preserve spaces when outputting a shell variable?
Use More Quotes! echo "$jpat"
will do what you want.
There is another issue with what you're doing: Command substitutions will remove trailing newlines. It's not an issue in the printf
command you're using, but for example assigning jpat=$(printf " %6i\n" "$jj")
would give you exactly the same result as your command.
How to preserve trailing whitespace in bash function arguments?
What happened to the trailing whitespace in the first argument?
The whitespace was included on the
echo
command line, but was discarded by the shell, the same as if you had typed:echo -n Testing...
^
|----- there is a space hereHow can preserve it?
Quote your variables:
function foo {
echo -n "$1"
echo "$2"
}
How to preserve line breaks when storing command output to a variable?
Quote your variables. Here is it why:
$ f="fafafda
> adffd
> adfadf
> adfafd
> afd"
$ echo $f
fafafda adffd adfadf adfafd afd
$ echo "$f"
fafafda
adffd
adfadf
adfafd
afd
Without quotes, the shell replaces $TEMP
with the characters it contains (one of which is a newline). Then, before invoking echo
shell splits that string into multiple arguments using the Internal Field Separator
(IFS), and passes that resulting list of arguments to echo
. By default, the IFS
is set to whitespace (spaces, tabs, and newlines), so the shell chops your $TEMP
string into arguments and it never gets to see the newline, because the shell considers it a separator, just like a space.
Command line args with spaces
Use an array:
args=('one two' 'foo bar')
getParams.sh "${args[@]}"
Using args="'one two' 'foo bar'"
wont work, because the single quotes retain their literal value when inside double quotes.
To preserve multiple spaces in the arguments (and also handle special characters such as *
), you should quote your variable:
while [[ $# -gt 0 ]]
do
echo "$1"
shift
done
Command line arguments with spaces to a C program through shell-wrapper script
Replace the use of ./data_sniffer.bin $*
with ./data_sniffer.bin "$@"
in your wrapper script and the arguments should be forwarded in a correct manner.
More regarding the difference between $*
, $@
and "$@"
can be found here.
the author of this question changed it completely and came forward with more information regarding the matter, I will let everything already written stand but please remember that this was written before his/her last edit..
Regarding argv
..
It doesn't require much from you as a developer, I'm tempted (and it's much more truthful) to say that it requires nothing of you.
Arguments passed to the application is handled by the shell executing the binary, doing this below should definitely work the way you want it to (even though I find it odd that you are claiming that the current shell doesn't handle '\ '
correctely):
./data_sniffer '/mnt/pod/movies/some test movie file.avi'
./data_sniffer /mnt/pod/movies/some\ test\ movie\ file.avi
# there should be no difference between the two
My recommendation(s)
Have you tried doing
printf ("argv[1]: %s\n", argv[1]);
in the beginning of main to validate the contents of it?Are you sure that you are invoking the correct binary with the correct command-line arguments?
Sadly the only reasonable thing to write is that you are doing something wrong. We are however unable to answer what without further information regarding the issue.
I find it very hard to believe that there is a bug in your shell, even though that is of course possible - I doubt it.
Parsing the command-line into argv
isn't something that you as a developer should worry about, there are no enforced functionality that you have to implement for the binary itself to handle spaces in it's argument(s).
Save path with spaces in Makefile variable
You could replace:
SHELL:=/usr/bin/env bash
with one of these (or with whatever path directly leads to Bash's executable):
SHELL:=/bin/bash
SHELL:=/usr/bin/bash
SHELL:=bash
which would eliminate the space from the equation.
That being said, you should also be able to run the commands directly, i.e.:
./utils/tests.sh
instead of:
${SHELL} ./utils/tests.sh
which would eliminate the need to set and use variable SHELL
altogether.
Related Topics
What Context Does the Scheduler Code Run In
How to Know the Interrupt/Gpio Number for a Specific Pin in Linux
How to Do Http-Request/Call with JSON Payload from Command-Line
How to Find My Shell Version Using a Linux Command
Pass Parameter to an Awk Script File
/Lib64/Ld-Linux-X86-64.So.2: No Such File or Directory Error
Docker Load and Save: "Archive/Tar: Invalid Tar Header"
How to Get the Variable Value Inside the Eof Tags
How to Make Travis Ci Test Package for Linux, Os X, Windows
Process Permanently Stuck on D State
How to Clear the Scrollback in the Screen Command
How to Confirm Redhat Enterprise Linux Version
How to Continuously Display a File of Its Last Several Lines of Contents
In a Linux Shell How to Process Each Line of a Multiline String
How to Automatically Pipe to Less If the Result Is More Than a Page on My Shell