echoing a shebang to a file - terminal

I am trying to echo a shebang to a file.
vincent#vincent-X751LJ:~$ echo "#!/usr/bin/sh" > file
echo "#/usr/bin/sh" > file
vincent#vincent-X751LJ:~$ cat file
#/usr/bin/sh
The "bang" vanishes (even in my history !). Everything looks like I never typed !. I have also tried without the double quotes. Same result.
It does not happen if I echo just #!
vincent#vincent-X751LJ:~$ echo "#!" > file
vincent#vincent-X751LJ:~$ cat file
#!
The reason is certainly so simple...
The only reference to a shebang echoing problem is on SO (How to echo a shebang in cmake COMMAND) but the problem is different on my side.
Thanks

I'm not sure why this happens exactly, but using single quotes (to disable shell escaping) should remedy this.
See Difference between single and double quotes in Bash

Related

Bash script: any way to collect remainder of command line as a string, including quote characters?

The following simplified version of a script I'll call logit obviously just appends everything but $1 in a text file, so I can keep track of time like this:
$ logit Started work on default theme
But bash expansion gets confused by quotes of any kind. What I'd like is to do things like
$ logit Don't forget a dark mode
But when that happens of course shell expansion rules cause a burp:
quote>
I know this works:
# Yeah yeah I can enclose it in quotes but I'd prefer not to
$ logit "Don't forget a dark mode"
Is there any way to somehow collect the remainder of the command line before bash gets to it, without having to use quotes around my command line?
Here's a minimal working version of the script.
#!/bin/bash
log_file=~/log.txt
now=$(date +"%T %r")
echo "${now} ${#:1}" >> $log_file
Is there any way to somehow collect the remainder of the command line before bash gets to it, without having to use quotes around my command line?
No. There is no "before bash gets into it" time. Bash reads the input you are typing, Bash parses the input you are typing, there is nothing in between or "before". There is only Bash.
You can: use a different shell or write your own. Note that quotes parsing like in shell is very common, you may consider that it could be better for you to understand and get used to it.
you can use a backslash "\" before the single quote
$ logit Don\'t forget a dark mode

No such file or directory when exporting files using bash script [duplicate]

I've written this script:
#!/bin/bash
file="~/Desktop/test.txt"
echo "TESTING" > $file
The script doesn't work; it gives me this error:
./tester.sh: line 4: ~/Desktop/test.txt: No such file or directory
What am I doing wrong?
Try replacing ~ with $HOME. Tilde expansion only happens when the tilde is unquoted. See info "(bash) Tilde Expansion".
You could also do file=~/Desktop without quoting it, but if you ever replace part of this with something with a field separator in it, then it will break. Quoting the values of variables is probably a good thing to get into the habit of anyway. Quoting variable file=~/"Desktop" will also work but I think that is rather ugly.
Another reason to prefer $HOME, when possible: tilde expansion only happens at the beginnings of words. So command --option=~/foo will only work if command does tilde expansion itself, which will vary by command, while command --option="$HOME/foo" will always work.
FYI, you can also use eval:
eval "echo "TESTING" > $file"
The eval takes the command as an argument and it causes the shell to do the Tilde expansion.

Including "cat" command in unix shell Here Document

I'm trying to create a Here Document which is a shell script that includes the cat command. Of course, it fails when encountering the 2nd cat. I'm performing a lot of substitutions as well, so can't use the "DOC" escape trick.
myfile="/tmp/myipaddr"
cat >/usr/bin/setIPaddress <<_DOC_
...
OUT=`cat $myfile`
...
_DOC_
I supposed I could echo into a file, but that seems kludgy and I have a lot of quotes and backticks I'd need to escape?!? Any other thoughts?
Suppose the file contains
hello world
As written, the script you generate will contain the line
OUT=hello world
because the command substitution is performed immediately.
At the very least, you need to quote the line in the here document as
OUT="`cat $myfile`"
I suspect what you want is to include the literal command substitution in the resulting shell script. To do that, you would want to quote the backticks to prevent them from being evaluated immediately. Better still, use the recommended form of command substitution, $(...), and quote the dollar sign.
cat >/usr/bin/setIPaddress <<_DOC_
...
OUT=\$(cat $myfile)
...
_DOC_
/usr/bin/setIPaddress will then include the line
OUT=$(cat /tmp/myipaddr)

Script isn't writing anything after $ to text file

In a bash script I have it is supposed to write certain lines to a file.
This is what it supposed to write:
echo "export ROS_PACKAGE_PATH=/home/forklift/forklift-workspace:$ROS_PACKAGE_PATH" >> ~/.bashrc
and this is what it writes in the file:
export ROS_PACKAGE_PATH=/home/forklift/forklift-workspace:
how do I fix this?
I'm using Ubuntu
Any help is appreciated!!
This is expected if the variable $ROS_PACKAGE_PATH is not defined (or equal to "") when echo is called. If I understand what you are trying to do, then you can just replace the double-quotes with single quote to prevent this behaviour. Thus
echo 'export ROS_PACKAGE_PATH=/home/forklift/forklift-workspace:$ROS_PACKAGE_PATH' >> ~/.bashrc
Should add the line
export ROS_PACKAGE_PATH=/home/forklift/forklift-workspace:$ROS_PACKAGE_PATH
to your .bashrc.
The $ROS_PACKAGE_PATH in the string is being interpolated as a variable, but it doesn't exist in the environment so it just comes out blank.
It needs to be escaped with a \, like this:
echo "export ROS_PACKAGE_PATH=/home/forklift/forklift-workspace:\$ROS_PACKAGE_PATH" >> ~/.bashrc
For more in-depth information on parameter expansion, this is pretty comprehensive: http://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

How to accommodate spaces in a variable in a bash shell script?

Hopefully this should be a simple one... Here is my test.sh file:
#!/bin/bash
patch_file="/home/my dir/vtk.patch"
cmd="svn up \"$patch_file\""
$cmd
Note the space in "my dir". When I execute it,
$ ./test.sh
Skipped '"/home/my'
Skipped 'dir/vtk.patch"'
I have no idea how to accommodate the space in the variable and still execute the command. But executing this the following on the bash shell works without problem.
$ svn up "/home/my dir/vtk.patch" #WORKS!!!
Any suggestions will be greatly appreciated! I am using the bash from cygwin on windows.
Use eval $cmd, instead of plain $cmd
Did you try escaping the space?
As a rule UNIX shells don't like non-standard characters in file names or folder names. The normal way of handling this is to escape the offending character. Try:
patch_file="/home/my\ dir/vtk.patch"
Note the backslash.

Resources