Bash script adding special characters to the end of any file I create - linux

I am creating a bash script to create backups, however the bash scripts mkdir is naming the folder with some sort of special characters on the end. if I ls the directory the name show up with a ? on the end which I know is terminals way of showing unrecognized special characters.
How do I get my bash script to to create the folder without adding on this special unrecognized character to the end.
Any help is appreciated.
See script below:
#!/bin/bash
mkdir -p "/var/backups/Backup"
mysqldump -u user1 -ptest DB tbl1 > "/var/backups/Backup/tbl1.sql"
DAY=$(date +%Y%m%d%H%M%S)
zip -r /var/backups/bkup-$DAY.zip /var/backups/Backup
cat -A shows the following:
#!/bin/bash^M$
mkdir -p "/var/backups/Backup"^M$
mysqldump -u user1 -ptest DB tbl1 > "/var/backups/Backup/tbl1.sql"^M$
DAY=$(date +%Y%m%d%H%M%S)^M$
zip -r /var/backups/bkup-$DAY.zip /var/backups/Backup

the ^M (CR) characters in your cat -A output are the problem: the shell treats only LF as the "end of line" marker, and the preceding CR character becomes part of the previous word. only '/' and '\0' characters are forbidden in pathnames in POSIX(ish) systems.
you can fix your script with dos2unix or with
vim yourfile.sh
:set ff=unix
:wq

Related

Customization of regular expressions in Linux shell

I am working on the definition of regular expressions. With the command
file=`echo $2 | sed -e "s/\&/\&/g" \
-e "s/</\</g" \
-e "s/>/\>/g" \
-e "s/'/\&apos;/g"`
a shell script accesses a file in a file system and then continues editing the file. That works pretty well. However, it can not be used to capture files whose file path contains two spaces in succession.
Is it possible to adapt this command character so that such special cases are included in the file path?
The easiest thing to do is put the filename in quotes on the command line. For example:
$ script.sh arg "file name"
The other thing you can do, if the the file name is the last argument the script receives, is to take all of the remaining command line args. E.g.:
shift # Shifts off the first argument, so $2 is the first one
file=`echo $* | sed ....`
The file name incl. File path I give the command already.
The program "set_attributes" sets with option -w the value 1 to the specified file "path to file"
./set_attributes -u user -p password -w 1 server_2 "path to file"
./set_attributes -u user -p password -w 1 server_2 "/example/folder
1/filename.jpg
This file gets the program "set_attributes" not handled because there are two blank characters in the file path.

perl -p -i -e inside a shell script

#!/usr/bin/env bash
DOCUMENT_ROOT=/var/www/html/
rm index.php
cd modules/mymodules/
perl -p -i -e 's/x.xx.xx.y/dd.dd.ddd.dd/g' `grep -ril y.yy.yy.y *`
shows shows a warning
-i used with no filenames on the command line, reading from STDIN.
It prevents running rest of the scripts.
Any solutions ?
Actually I need to run
perl -p -i -e 's/x.xx.xx.y/dd.dd.ddd.dd/g' `grep -ril y.yy.yy.y *`
Inside a shell script
I am using ubuntu with docker.
Let's look at this a step at a time. First, you're running this grep command:
grep -ril y.yy.yy.y *
This recursively searches all files and directories in your current directory. It looks for files containing the string "y.yy.yy.yy" in any case and returns a list of the files which contain this text.
This command will return either a list of filenames or nothing.
Whatever is returned from that grep command is then passed as arguments to your Perl command:
perl -p -i -e 's/x.xx.xx.y/dd.dd.ddd.dd/g' [list of filenames]
If grep returns a list of files, then the -p option here means that each line in every file in the list is (in turn) run through that substitution and then printed to a new file. The -i means there's one new file for each old file and the new files are given the same names as the old files (the old files are deleted once the command has run).
So far so good. But what happens if the grep doesn't return any filenames? In that case, your Perl command doesn't get any filenames and that would trigger the error that you are seeing.
So my (second) guess is that your grep command isn't doing what you want it to and is returning an empty list of filenames. Try running the grep command on its own and see what you get.

bash script file copied with additional character in filename

I am writing a bash script to copy some config files. I run the file using sudo bash configure.sh.
#!/bin/bash
cp config/ocr_pattern /usr/share/tesseract-ocr/tessdata/ocr_pattern
cp config/ocr_config /usr/share/tesseract-ocr/tessdata/tessconfigs/ocr_config
However when I view the changes made, ocr_config is copied correctly but ocr_pattern is copied with ocr_pattern? as the filename instead of ocr_pattern. There is an additional character ? behind in the filename for ocr_pattern. What is the issue here?
cat -A
#!/bin/bash^M
cp config/ocr_pattern /usr/share/tesseract-ocr/tessdata/ocr_pattern^M
cp config/ocr_config /usr/share/tesseract-ocr/tessdata/tessconfigs/ocr_config
As shown by the output of cat -A, you have carriage return (\r) at the end of some lines causing the mentioned issues.
Remove those:
sed -i 's/\r$//' configure.sh
or just use dos2unix:
dos2unix configure.sh

use of sed substitute in shell script doesn't work

I have made an install script which basically inserts some RewriteRule right after RewriteEngine On line by using sed inside a shell script
#!/bin/bash
REWRITE_RULE="RewriteRule \^catalog\/category\/view\/id\/([0-9]+)$ http:\/\/localhost\/app\/#?c=$1 [NE,L,R=301]"
FILE_PATH=".htaccess"
sed -i "s/RewriteEngine on/RewriteEngine on\n\n$REWRITE_RULE/g" $FILE_PATH
it does nothing but gives some error like
: No such file or directory
I tried same commands in shell and it worked without any issues and updated my .htaccess file
I am new to shell scripting so don't know the difference of using same command through shell and through script.. please guide
The script itself is fine. Are you sure that the lines posted above are exactly as you took them from your script?
The error message indicates that you provided an empty name as the filename, thus I suggest you put a
echo "FILE_PATH: $FILE_PATH"
directly before your sed command in order to check whether the variable is set correctly.
You'll find that your script contains carriage returns due to being saved with DOS end-of-line characters. Use tr -d '\r' <brokenscript >fixedscript to fix your script.
Here's a copy of a session with the problem reproduced and fixed:
$ cat file
var=foo
$ cat myscript
sed -i s/foo/bar/ file
$ bash myscript
: No such file or directory
$ shellcheck myscript
In myscript line 1:
sed -i s/foo/bar/ file
^-- SC1017: Literal carriage return. Run script through tr -d '\r' .
$ tr -d '\r' < myscript > fixedscript
$ bash fixedscript
$ cat file
var=bar
$

Can Bash History Expansion be used to reference something in the same command?

Bash has this feature called history expansion where you can use shortcuts that expand to things you've typed previously into bash.
Example: !! - expands into previous command
$> rm -f /var/log/access.log
rm: /var/log/access.log: Permission Denied
$> sudo !!
sudo rm -f /var/log/access.log
$> echo "i am teh hax"
Another: !$ - expands into last arg of previous command
$> echo "no one was here" > access.log
$> cp !$ /var/log/
cp access.log /var/log/
Does bash, or some other shell, have the ability to use substitution shortcuts within the command itself?
Something like
$> cp httpd.conf !$.bak
cp httpd.conf httpd.conf.bak
$> echo "SABOTEUR!!!" > httpd.conf
I need to up my 1980's cyberpunk skills. Please Help.
by within the command itself, do you mean you want to refer to httpd.conf?
Then this is your solution in superuser
Using bash history expansion:
mv path/to/oldfile !#:1:h/newfile
where !#:1:h means: from the line you're currently typing (!#), take the first word (:1), then take only the path component (:h -- the head) from it.
The answer by justhalf is what you want.
But for your requirement, there is one more hack/misuse available.
sed -i.bak '' /path/to/file
e.g.
sed -i.bak '' httpd.conf
It will copy your file to another file with .bak appended.
Advantage: /path/to/file can contain wildcards/globs, or you can directly give a white-space separated list of files.

Resources