so im trying to create a bash script that runs on MAC command line to a remote server and uses some mv commands to move some files around but i also need it to open up a file and add a line to the top of the file and save it in the middle of the script heres what i have so far:
(this is adjusting permissions so i can edit the file)
chef-client -r xxxxxxredactedxxxxxxredacted
cd /xxx/postgresql/xx/main/
Sudo chmod -R 775 filenamehere
sudo chown -R postgres:postgres filenamehere
read -p 'Enter the IP: ' ip
echo "Enter the file name :"
read -r filename
echo "Type this below: host all all "$ip"/24 trust : "
read -r line
cd /etc/postgresql/12/main/
printf '1i\n%s\n.\nwq\n' "$line" | ed "$filename". <-- **this is the problem line**
^ this command gives me permission denied because of access, for some reason i can edit it with vim but not this command
its worth noting these commands arent ran through my pc so my ability to move files is somewhat limited, its ran through SSM ing into an IP of a test enviroment through my command line
Normally I manually VIM into the file and add a line to the top
Don't know if you're using echo to output the prompts because you didn't know about the -p read option or you wanted the new lines.
You could use command grouping to add a line at the top of your file.
read -p "Have you copied a file to the data shipper? (yes/no)"
if [ "$REPLY" == "yes" ]; then
read -p "Enter a variable: " VARIABLE
read -p "Enter a file name: " FILE
cd /var/xxxredacted////
cd /tmp/
sudo mv "$FILE" /varxxxredactedxxxxxxxx/drop
cd /var/redactedxxxxredactedxx/drop
sudo unzip "$FILE"
fi
read -p "Enter the file name:\n" FILENAME
read -p "Enter the line to be added:\n" LINE
{ echo $LINE; cat "$FILENAME"; } > "${FILENAME}.new"
mv "$FILENAME"{.new,}
sed could be used too, if the line had to go to a specific line :
# If \n is omnited, $LINE will just be inserted on
# line 1 instead of appending a new line
sed -i "${LINENB}s/$LINE\n/" $FILENAME
Related
So I was just playing around and created this simple Shell script:
TestScript.sh
#!/bin/bash
read -p "read or write? " INP
if [[ "${INP}" == "write" ]]
then
read -p "Write your text: " TEXT
touch /usr/share/textfile.txt
echo "${TEXT}" >> /usr/share/textfile.txt
else
cat /usr/share/textfile.txt
fi
which of course can easily read and write into a file under /usr after gaining sudo priviliges:
sudo sh TestScript.sh
Based on this file I create a test PKGBUILD to install TestScript.sh via pacman later on:
PKGBUILD
# Maintainer: Your Name <youremail#domain.com>
pkgname='test-script'
pkgver=1
pkgrel=1
pkgdesc="AUR test package"
arch=('x86_64')
license=('custom')
source=('TestScript.sh')
md5sums=('SKIP')
package() {
mkdir -p "${pkgdir}/usr/bin"
cp "${srcdir}/TestScript.sh" "${pkgdir}/usr/bin/TestScript"
chmod +x "${pkgdir}/usr/bin/TestScript"
}
Followed by
makepkg
sudo pacman -U test-script-1-1-x86_64.pkg.tar.xz
I can run
TestScript
from the command line. But just as I thought, I am unable to write into /usr/share/textfile.txt .
I was searching the Arch-Wiki page up and down, but I couldn't find out how to handle this situation. I basically just want to have a location where I can properly read and write a file without messing up the user space.
Does anyone have an idea?
Trying to read values from a file inside gitlab-ci.yml file:
#!/usr/bin/bash
- IN_FILE="base_dir/apps_namespaces.txt"
- echo "IN_FILE = " > $IN_FILE
- while IFS= read -r line || [ -n "$line" ]; do
- echo "Name read from file - " > $line
- done < $IN_FILE
But this script fails with error - "/usr/bin/bash: line 131: read: line: invalid number"
Whereas same logic works in a plain script file, having following code:
#!/bin/bash
while IFS= read -r line || [[ -n "$line" ]];
do
echo "Text read from file: $line"
done < "$1"
when ran this script using command : ./scrpt apps_namespaces.txt
it rans and print each line.
What can be done if needs a long list to be read inside a gitlab-ci yml ?
Check if you can emulate this gitlab-ci.yml loop example, which:
does not include the shebang (#!/bin/bash)
does not have a - in front of each line
script:
[...]
- while read line; do
echo $line;
./sireg-linux exec --loader-sitemap-sitemap \"$line\" >> ./output/${line##*/}_out.txt;
done < sitemap-index
Of course, the alternative is to put the logic in a script, called from the pipeline, as documented in gitlab-org/gitlab-runner issue 2672
This is basic Unix, you just need your script to be executable in your git repo
chmod a+x scripts/test.sh
git add scripts/test.sh
git commit "fixing permissions"
git push
don't put /usr/bin/env for sh nor bash: both are 100% guaranteed to be present as #! /bin/sh or /bin/bash if bash is installed, or at least a much guaranteed to be there than /usr/bin/env to exists (and using env sh is not very good security)
A better approach which I followed:
put the logic to read file contents inside a script file. And refer this script inside gitlab-ci.yml worked.
It is cleaner and manageable.
I am trying to make a simple bash script to run nano command via bash so that I don't need to type nano filename every time, I just execute ./n and I will be asked for enter file name and I type the file name and done, the file should open using nano.
I'm trying this but it is somewhere wrong,
#!/bin/bash
echo -n "Enter file name: "
read INPUT
echo "$INPUT" >> "$JD"
nano JD
Solve is very simple
this script do it:
#!/bin/bash
echo -n "Enter file name :"
read FileName
touch $FileName
nano $FileName
save as the "nanoScript.sh" like
and open terminal and write :
chmod +x nanoScript.sh
and you can this : ./nanoScript.sh
it will create file and open with nano
I am trying to do the following in a bash file:
mybash.sh myinputfile.txt myloopfile.csv
Create a for loop, that reads myloopfile.csv line by line, and then creates a folder which will take the line number as the folder name prefixed to "folder", ex. folder1, folder2...
and then inside this folder$i create a folder called input and another called output.
write the line$i content into a file called myline.txt and put this file inside the folder$i/input
and copy the file myinputfile.txt that i will pass as a parameter to the bash file inside the folder$i/input as well.
and then run my personal script that takes two arguments:
python myscript.py -i ./folder$i/input -o ./folder$i/output
and done!
myfile.csv
101,1001,10012,100121
102,101213,11122.1,12.15
103,122.15,155.2,1515.54
104,154.4,4551.1,454
what I currently have:
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
mkdir ./folder$line
echo "$line" >> Folder$line/input/myline.txt;
cp myinputfile.txt Folder$line/input
python myscript.py -i ./folder$i/input -o ./folder$i/output
done < "$1"
the problem is that I can't get the line index to pass it as a suffix to the folder name, so I currently get the line content.and I don't know how to read the two files from the arguments that i pass to the mybash.sh.
Use a counter to keep track of line numbers:
#!/bin/bash
input_file=$1
csv_file=$2
count=1
while IFS= read -r line || [[ -n "$line" ]]; do
input_dir="./folder$count/input"
output_dir="./folder$count/output"
mkdir -p "$input_dir" "$output_dir"
printf '%s\n' "$line" > "$input_dir/myline.txt"
cp "$input_file" "$input_dir"
python myscript.py -i "$input_dir" -o "$output_dir"
((count++))
done < "$csv_file"
I have a script called autoinstall:
#!/usr/bin/sh
echo "Installasi membutuhkan free space minimal 2MB, pastikan ada punya cukup space di router anda"
read -p "Anda yakin ingin melanjutkan installasi?(y/n) " -n 1 -r
echo ""
if [[ $REPLY = ^[Yy]$ ]]
then
cd /
cd /tmp/
tar -xvf OpenWrt_Angel_Beats_Edition_v1.3.3.tar -C /
chmod -R 744 /root/crt
chmod 744 /www/wget/wget_download.sh
chmod 744 /usr/bin/gsm
chmod 744 /usr/bin/profile
opkg update && opkg install elinks
cp /etc/rc.local /etc/rc.local.backup
cat > /etc/rc.local << END
#!bin/sh
# /etc/rc.local: Local system initialization script.
#
# Put any local startup commands in here. Also, if you have
# anything that needs to be run at shutdown time you can
# make an /etc/rc.d/rc.local_shutdown script and put those
# commands in there.
sh /www/wget/wget_download.sh > /dev/null 2>&1 &
exit 0
END
killall sh /www/wget/wget_download.sh
sh /www/wget/wget_download.sh > /dev/null 2>&1 &
echo "File backup /etc/rc.local.backup telah dibuat, gunakan file ini untuk mengembalikan konfigurasi rc.local anda yang dulu jika diperlukan"
echo "Installasi selesai. Jangan lupa di akun openvpn yang digunakan (/root/crt/xxx.ovpn) tambahkan baris ini:
script-security 2
up client-connect.sh"
else
echo ""
echo "Installasi dibatalkan"
fi
Every command that I put in the first line always gets the error above (line 1:xxx not found) and I'm sure I've typed in the correct command, even echo gives the error like that, how do I solve this?
There can be two problems here:
The file doesn't exist. Usually, for sh, the path is /bin/sh, so it should be #!/bin/sh
You're editing the file on Windows. Windows uses CR+LF as line ending. Unix (and Linux) uses just LF. So for Linux, the command reads "execute /bin/sh<CR> and sh<CR> doesn't exist.
Solution: When editing the file, make sure you use Unix line endings.
The file might have been edited with an editor that insert a Unicode BOM (Byte Order Mark).
Have a look to the first line contents with:
od -c autoinstall | head -1
or
hd -n 16 autoinstall
If you see unexpected characters before #!/usr/bin/sh, you might try one of the methods described here Using awk to remove the Byte-order mark to remove the BOM.