Linux: Use parameter as file shortcut - linux

Cheers everyone :)
I'm trying to make a linux script. This script shall be called with one parameter, a file stored in my home directory. I can't seem to use
cat $var1 >> $1
So i have this variable $var1 and I want to save it in a file that does exist and its name is given in $1
Anyone help me please!

The cat command shows the contents of a file.
Unless the value of $var1 is a file that you want to 'copy' to $1, it won't work (probably gives a 'file not found' kind of error).
The easiest solution, I can think of, is to echo the variable:
echo "$var1" >> "$1"
As stated by #glglgl it is better to put the variable between double quotes. They prevent spaces messing up the command as they split a parameter into multiple parameters

Then you want to create a script that saves things in the file you indicate as a parameter.
file_name=$1 #you get the parameter
...do things...
echo "everything you've done" >> $file_name #case want to append
echo "everything you've done" > $file_name #case want to overwrite

Related

How to read a line that contains non-string command inside a file via bash

Below is a snapshot of a file called ".bashrc":
I'm beginner in bash and What i'm trying to do in bash is to check if the last two lines inside the file exist and correctly written like for example :
if [ export PATH=/opt/ads2/arm-linux64/bin:$PATH ]
then
echo "found system variable lines"
else
echo "systemvariables do not exists, please insert it in .bashrc"
fi
However, this doesn't seem to be trivial since the tow lines to be shared are not pure string lines.
Thanks in advance
Use grep to find stuff in file contents.
# if file .bashrc contains the line exactly export PATH=....
if grep -Fxq 'export PATH=/opt/ads2/arm-linux64/bin:$PATH' .bashrc ; then
echo "found system variable lines"
else
echo "systemvariables do not exists, please insert it in .bashrc"
fi
Read man grep and decide if you want or not the -F and -x options in grep. For sure research and learn regex - I recommend regex crosswords available on the net. Research also difference between single quoting and double quoting in shell. Remember to check scripts with http://shellcheck.net

Passing argument into shell script as a form of txt file

I would like to know how to access the contents of a variety of txt files by passing arguments into shell scripts. I'll have different files and I'm expecting to execute with this command:
./script.sh FileA.txt
What should I put into my shell script so that I can access and manipulate the contents of the files?
I tried this but it outputs 0:
echo "$#"
I also tried these, but both output nothing:
for i in $1
do
echo "$i"
done
echo "$1"
To sum up the contents see this link to understand bash arguments more https://tecadmin.net/tutorial/bash-scripting/bash-command-arguments/ . Also as #Barmar said, to iterate through a list of arguments of unknown quantity use for i in "$#" .
edit
and as #Barmar said, $1 is simply the name of the argument. So echoing $1 will just echo the name.
I don't understand your question fully. Lets assume you have list of file names in a text file "FileA.txt".
And you wanted to run some commands for each file in the "FileA.txt" file.
Can you try below:
for i in `cat $1`
do
echo $i
done

How do I echo a variable with a star in it with added text?

So I am creating a variable and I want to echo it with an addition to the end like so:
I have a file: Filename-08-10-2017.txt
I create a variable:
myvariable=Filename*.txt
When I echo that variable:
echo $myvariable
it outputs Filename-08-10-2017.txt
But I want to change the name to .zip
So I am trying to go:
echo $myvariable.zip and have it output Filename-08-10-2017.txt.zip
however it outputs:
Filename*.txt.zip
How do I go about having it output the way I want?
Thanks.
EDIT:
I kind of figured it out.
I saved a new variable as $($myvariable) which saved the output.
The file name comes from glob expansion. If you want to iterate all files by using glob expansion, you can :
myvariable=Filename*.txt
for f in $myvariable; do echo $f; done
If you want to "disable" the glob expansion, e.g. get literial Filename*.txt by echo $myvariable, you can either set -f or just wrap the variable by double quote: echo "$myvariable".
To maniuplate the text you can do something like:
for f in $myvariable; do echo $f"whatever_like_zip"; done
if you want to do some text substitution, you can
for ... echo ${f/%txt/zip} ; done
It will change all txt file name to zip.
Also if you want to rename the file, change the above echo... into
mv "$f" "yourNewNameHere"
Anyway by reading your question I'm not quite clear, what do you really want.
Yuo can use sed
try this
file="test.txt"
newext=$(echo "$file" | sed -e "s|txt|zip|g")
echo $newext

Bash write into file that is named by a variable

I am working on creating a simple script to make it easy to set up a virtual host on Apache server. Currently I don't seem to be able to write the config file because it's in a variable. How do I get around it. Here is my code that does not work.
siteConf="/etc/apache2/sites-available/$domain.conf"
echo "creating conf file"
echo "<VirtualHost *:80>" >> $siteConf
echo "ServerName *.$domain" >> $siteConf
echo "DocumentRoot $publicHtmlLoc" >> $siteConf
echo "DirectoryIndex index.php" >> $siteConf
echo "ServerAlias $database.newphp.junglecoders.dk" >> $siteConf
echo "</VirtualHost>" >> $siteConf
I am running the script with the bash command.
Edit: The Error i get is this
$siteConf: ambiguous redirect
Domain comes from here:
echo "Write websiter url example.com, no sub dir allowed"
read -p "Name: " domain
As suggested in comments its the path that is wrong, i tried to echo out the variable and i can see it has removed the '.' chars from some reason and left a space instead, why would the script do that ?
Edit2:
Was using IFS earlier in the script, to split the the domain name
The code looks as if it should work. You might do better with
{
echo "<VirtualHost …>"
…
echo "</VirtualHost>"
} > $siteConf
(or >> $siteConf if you really want to add to the existing file). That does a single redirection for all the output, and truncates the file. It is also a good idea as a general rule to enclose uses of variables in double quotes:
} > "$siteConf"
Basic debugging for shell scripts:
What do you get from bash -x your-script.sh?
You get 'ambiguous redirect' when the variable named doesn't exist or is empty, or if it expands to two or more words. That suggests that the first line of your script isn't an accurate representation of what you've got, but it is hard to guess how you've got it wrong. Misspelled name, or an unwanted space are probably the most likely, but it could be something else.
Alright looks like I needed to wrap it like in quotes like in the answer Getting an 'ambiguous redirect' error that antak suggested.
That's a good question to cross-reference. At one point, this question was closed as a duplicate of it, but the issue here turned out to be about IFS being set, which is not an alternative source of trouble identified in that other question.
Have you gone messing with IFS at any point in the script?
Yes — been doing IFS for splitting the URL into parts.
Note that:
set_with_spaces="name1 name2"
echo Hi >> $set_with_spaces
yields
bash: $set_with_spaces: ambiguous redirect too.
Two names were generated from one variable.
$ IFS=.
$ domain=abc.def.ghi.jkl
$ echo $domain
abc def ghi jkl
$ echo "$domain"
abc.def.ghi.jkl
$ IFS=$' \t\n'
$ echo $domain
abc.def.ghi.jkl
$
If you have been messing with IFS, then its current value is probably altering how the names are being interpreted. Reinstate it to its default value (blank, tab, newline):
IFS=$' \t\n'

Shell - Write variable contents to a file

I would like to copy the contents of a variable (here called var) into a file.
The name of the file is stored in another variable destfile.
I'm having problems doing this. Here's what I've tried:
cp $var $destfile
I've also tried the same thing with the dd command... Obviously the shell thought that $var was referring to a directory and so told me that the directory could not be found.
How do I get around this?
Use the echo command:
var="text to append";
destdir=/some/directory/path/filename
if [ -f "$destdir" ]
then
echo "$var" > "$destdir"
fi
The if tests that $destdir represents a file.
The > appends the text after truncating the file. If you only want to append the text in $var to the file existing contents, then use >> instead:
echo "$var" >> "$destdir"
The cp command is used for copying files (to files), not for writing text to a file.
echo has the problem that if var contains something like -e, it will be interpreted as a flag. Another option is printf, but printf "$var" > "$destdir" will expand any escaped characters in the variable, so if the variable contains backslashes the file contents won't match. However, because printf only interprets backslashes as escapes in the format string, you can use the %s format specifier to store the exact variable contents to the destination file:
printf "%s" "$var" > "$destdir"
None of the answers above work if your variable:
starts with -e
starts with -n
starts with -E
contains a \ followed by an n
should not have an extra newline appended after it
and so they cannot be relied upon for arbitrary string contents.
In bash, you can use "here strings" as:
cat <<< "$var" > "$destdir"
As noted in the comment by Ash below, #Trebawa's answer (formulated in the same room as mine!) using printf is a better approach than cat.
All of the above work, but also have to work around a problem (escapes and special characters) that doesn't need to occur in the first place: Special characters when the variable is expanded by the shell. Just don't do that (variable expansion) in the first place. Use the variable directly, without expansion.
Also, if your variable contains a secret and you want to copy that secret into a file, you might want to not have expansion in the command line as tracing/command echo of the shell commands might reveal the secret. Means, all answers which use $var in the command line may have a potential security risk by exposing the variable contents to tracing and logging of the shell.
For variables that are already exported, use this:
printenv var >file
That means, in case of the OP question:
printenv var >"$destfile"
Note: variable names are case sensitive.
Warning: It is not a good idea to export a variable just for the sake of printing it with printenv. If you have a non-exported script variable that contains a secret, exporting it will expose it to all future child processes (unless unexported, for example using export -n).
If I understood you right, you want to copy $var in a file (if it's a string).
echo $var > $destdir
When you say "copy the contents of a variable", does that variable contain a file name, or does it contain a name of a file?
I'm assuming by your question that $var contains the contents you want to copy into the file:
$ echo "$var" > "$destdir"
This will echo the value of $var into a file called $destdir. Note the quotes. Very important to have "$var" enclosed in quotes. Also for "$destdir" if there's a space in the name. To append it:
$ echo "$var" >> "$destdir"
you may need to edit a conf file in a build process:
echo "db-url-host=$POSTGRESQL_HOST" >> my-service.conf
You can test this solution with running before export POSTGRESQL_HOST="localhost"

Resources