2nd loop inside the script or asking to enter value - bash

I have written a code but I am having a problem to make the double loop in my bash script. This script should read all the files 1 by 1 in the given directory to upload but the value of "XYZ" changes for each file. Is there a way for me to make the code ask me to enter the "XYZ" every time it reads a new file to upload? (if possible with the name of the file read) like "please enter the XYZ value of 'read file's name'" I could not think of any possible ways of doing so. I also have the XYZ values listed in a file in a different directory so maybe can it be called like the do loop I did for the path? I might actually need to use both cases as well...
#!/bin/bash
FILES=/home/user/downloads/files/
for f in $FILES
do
curl -F pitch=9 -F Name='astn' -F
"path=#/home/user/downloads/files;$f" -F "pass 1234" -F "XYZ= 1.2" -
F time=30 -F outputFormat=json
"http://blablabla.com"
done

try following once.
#!/bin/bash
FILES=/home/user/downloads/files/
for f in $FILES
do
echo "Please enter the name variable value here:"
read Name
curl -F pitch=9 -F "$Name" -F
"path=#/home/user/downloads/files;$f" -F "pass 1234" -F "XYZ= 1.2" -
F time=30 -F outputFormat=json
"http://blablabla.com"
done
I have entered a read command inside loop so each time it will prompt user for a value, since you haven't provided more details about your requirement so I haven't tested it completely.

The problem was actually the argument. By changing it to:
-F Name="$Name"
solved the problem. Trying to link the argument such as only $Name or "$Name" causes a bad reception.

Related

Use drag and drop to populate bash scrip for awk [duplicate]

I compiled mplayer from source on Ubuntu. I didn't want to use a GUI but I wanted to make a executable bash file that gets the path from an file that gets dropped onto the bash file. How do I make such a thing possible?
I wanted to make it look something like this:
mplayer <get full path to file.file-ending>
I want the executable bash file to sit on my desktop ;)
If possible, I'd just like an rightclick -> start with mplayer function, but I don't know how to make one.
You can access arguments passed to the script with $1 (for the first argument). And also you should make a .desktop file so Nautilus (or your desktop manager) know what to do and use %u to pass the dropped path to the script.
For example you can create a file named DropOverMe.desktop:
[Desktop Entry]
Encoding=UTF-8
Name=Drop Over Me
Comment=Execute the script with the file dropped
Exec=gnome-terminal -e "/folder/to/the/script/launchme.sh \"%u\""
Icon=utilities-terminal
Type=Application
I use gnome-terminal as I have Ubuntu on my PC, use your preferred terminal application.
And the script could be something like:
#! /bin/bash
echo "Launched with $1" >> /tmp/history.log
Try:
#!/bin/bash
mplayer "$1"
The file path of the dropped file will be passed to the script file as the 1th command line argument.
In openned terminal
By using mate-terminal, gnome-terminal or konsole, you could use drag'n drop into oppened window.
This will send URL as tipped, with a space added, but without endline.
For this, run mplayer, I wrote this little loop function:
while IFS=$' \t\r\n' read -d '' -p "Wait for URL to play: " -rsn 1 str &&
[ "$str" ];do
while IFS= read -d '' -rsn 1 -t .02 char
do str+="$char"
done
if [ "$str" ] ;then
read -a req <<<"$str"
echo $req
mplayer $req
fi
done
First read will determine if something is comming or else end loop.
Second loop with very short timeout will read dropped URL as a single string
read -a req will split string to consider only 1st part

Bash - Read response to copy files or directory

I'm trying to write a shell script to copy a file based on user response. An example of what I am trying to do:
#!/bin/bash
echo "What is the name of the user?: "
read RESPONSE
cp /home/$RESPONSE/file.txt /home/$RESPONSE/backup/file_backup.txt
However, my copy command doesn't seem to be accepting the read variable correctly.
What am I doing wrong?
I figured out the issue. I had some commands in between and then had a second read RESPONSE command that was not required. In other words, as an example, I had this:
#!/bin/bash
echo "What is the name of the user?: "
read RESPONSE
rsync -a /home/$RESPONSE /backup
read RESPONSE
cp /home/$RESPONSE/file.txt /home/$RESPONSE/backup/file_backup.txt
Also,#GeorgeVasiliou had it right, I needed to also include it in quotes. So what works is:
#!/bin/bash
echo "What is the name of the user?: "
read response
rsync -a "/home/$response/" /backup
cp "/home/$response/file.txt" "/home/$response/backup/file_backup.txt"
The following code achieves what you want. It also checks to see if the user exists, and if the user has created a /backup/ folder before attempting to save the file (if user doesn't exist, then /home/user/... should also not exist and the script would fail).
#!/bin/bash
echo "What is the name of the user?: "
read response
checkuser1="$(getent passwd | cut -d: -f1 | grep -si "$response")"
if [ -z "$checkuser1" ]; then echo "No user with this name has been located!"; exit; fi
if [ ! -d /home/"$response"/backup/ ]; then echo "This user has not created the /home/"$response"/backup/ folder yet!"; exit; fi
cp /home/"$response"/file.txt /home/"$response"/backup/file_backup.txt
exit
Edit: the code above was edited to add a few improvements.

Automating Passphrase in a Bash Script (steghide, gpg, etc.)

I've been working on a series of bash scripts and I need to automate password entry for batch processing of files and actions.
This isn't for just one program, for example, sometimes it needs to be done for GPG, other times, steghide.
There is a specific reason this is being done and I understand the security elements behind it. This is considered and is negated by how the scripts are stored and working.
The passwords or passphrases are passed via command line arguments to the script and the password/phrase must be repeated many times programmatically.
Here is an example of what I am working with inside the script:
for f in $dir
do
steghide embed -cf $f -ef /path/to/secret.txt
done
This simply interactively asked this for every image however:
Enter Passphrase:
Re-enter Passphrase:
For every image in a directory, this password will be requested and so the password should be able to be stored in a variable and reused.
I have been working with steghide most recently but there will also be a need to automate passphrases with GPG at a later date, although there is no need for the methods to be the same.
man steghide:
-p, --passphrase
Use the string following this argument as the
passphrase. If your passphrase contains whitespace,
you have to enclose it in quotes, for example: -p
"a very long passphrase".
man gpg:
--passphrase string
Use string as the passphrase. This can only be used if only one
passphrase is supplied. Obviously, this is of very questionable
security on a multi-user system. Don't use this option if you can
avoid it.
It's untested publicly, rough around the edges, and can be improved... but here's a preview of some of my research scripts that haven't been merged into one of the GitHub projects I'm writing... definitely run shellcheck against the below script to catch any typos.
#/usr/bin/env bash
Var_stego_out_dir="${1}"
Var_stego_in_dir="${2}"
Var_stego_cover_dir="${3}"
Var_passphrase_file="${4}"
Var_passphrase="${5}"
Var_auto_pass_length="${6:-64}"
Func_build_array_of_paths(){
_dir="${1}"
_arr="${2}"
_file_extension_list="${3}"
if [ -d "${_dir}" ] && [ "${#${_arr}[#]}" = "0" ]; then
find "${_dir}" -xtype f | while read _path; do
case "${_path##*.}" in
${_file_extension_list//,/|})
declare -ag "${_arr}+=( ${_path} )"
;;
esac
done
fi
}
Func_enc_stego(){
_cover_file="${1}"
_enc_file="${2}"
_pass_file="${3}"
_output_file="${Var_stego_out_dir}/${_cover_file##*/}"
if [ -f "${_cover_file}" ] && [ -f "${_enc_file}" ]; then
_auto_passphrase="${Var_passphrase:-$(base64 /dev/random | tr -cd '[:print:]' head -c${Var_auto_pass_length})}"
if ! [ -f "${_output_file}" ]; then
steghide -p ${_auto_passphrase} -ef ${_enc_file} -cf ${_cover_file} -sf ${_output_file}
cat <<<"### ${_output_file} ### ${_auto_passphrase}" >> "${_pass_file}"
else
steghide -p ${_auto_passphrase} -ef ${_enc_file} -cf ${_cover_file} -sf ${_output_file}_$(date -u +%s)
cat <<<"### ${_output_file}_$(date -u +%s) ### ${_auto_passphrase}" >> "${_pass_file}"
fi
fi
}
Func_main(){
## Build array of file paths for cover file use
Func_build_array_of_paths "${Var_stego_cover_dir}" "Arr_cover_list" "au,AU,bmp,BMP,jpeg,JPEG,wav,WAV"
## Build array of file paths for embed file use
Func_build_array_of_paths "${Var_stego_in_dir}" "Arr_input_list" "gpg,GPG,txt,TXT"
let _arr_input_count=0
let _arr_cover_count=0
until [ "${_arr_input_count}" = "${#Arr_input_list}" ]; do
if [ -f "${Arr_cover_list[${_arr_cover_count}]}" ]; then
Func_enc_stego "${Arr_cover_list[${_arr_cover_count}]}" "${Arr_input_list[${_arr_input_count}]}" "${Var_passphrase_file}"
let _arr_cover_count++
let _arr_input_count++
elif [ -f "${Arr_cover_list[$((${_arr_cover_count}-1))]}" ]; then
Func_enc_stego "${Arr_cover_list[$((${_arr_cover_count}-1))]}" "${Arr_input_list[${_arr_input_count}]}" "${Var_passphrase_file}"
let _arr_input_count++
_arr_cover_count="$((${_arr_cover_count}-1))"
if
done
}
Func_main
Run above with the following portions filled-in
script.sh "/path/to/stego_out_dir" "/path/to/stego_in_dir" "/path/to/stego_cover_dir" "/path/to/passphrase_file"
## or define static passphrase
#script.sh "/path/to/stego_out_dir" "/path/to/stego_in_dir" "/path/to/stego_cover_dir" "/path/to/passphrase_file" "passphrase"
Note saving the passphrase and file in plain-text like the above does is very bad practice, and because the OP stated that they also where looking at GnuPG automation too, readers and the OP"s author should look-up Perinoid_Pipes; and for specifically the GnuPG_Gen_Key.sh script and functions starting with Func_dec_* within the Paranoid_Pipes.sh for working/tested examples of automation involving GnuPG passphrases; and for protecting the passphrases written by the above script look-up functions starting with Func_enc_* within the Paranoid_Pipes.sh script for how the mkfifo command and resulting named pipe is used to automate encryption of most data types. Hint the fourth example argument "/path/to/passphrase_file" would point to an encrypting named pipe made by the linked script to keep things a bit more secure ;-)

Create executable bash script that accepts drag & drop

I compiled mplayer from source on Ubuntu. I didn't want to use a GUI but I wanted to make a executable bash file that gets the path from an file that gets dropped onto the bash file. How do I make such a thing possible?
I wanted to make it look something like this:
mplayer <get full path to file.file-ending>
I want the executable bash file to sit on my desktop ;)
If possible, I'd just like an rightclick -> start with mplayer function, but I don't know how to make one.
You can access arguments passed to the script with $1 (for the first argument). And also you should make a .desktop file so Nautilus (or your desktop manager) know what to do and use %u to pass the dropped path to the script.
For example you can create a file named DropOverMe.desktop:
[Desktop Entry]
Encoding=UTF-8
Name=Drop Over Me
Comment=Execute the script with the file dropped
Exec=gnome-terminal -e "/folder/to/the/script/launchme.sh \"%u\""
Icon=utilities-terminal
Type=Application
I use gnome-terminal as I have Ubuntu on my PC, use your preferred terminal application.
And the script could be something like:
#! /bin/bash
echo "Launched with $1" >> /tmp/history.log
Try:
#!/bin/bash
mplayer "$1"
The file path of the dropped file will be passed to the script file as the 1th command line argument.
In openned terminal
By using mate-terminal, gnome-terminal or konsole, you could use drag'n drop into oppened window.
This will send URL as tipped, with a space added, but without endline.
For this, run mplayer, I wrote this little loop function:
while IFS=$' \t\r\n' read -d '' -p "Wait for URL to play: " -rsn 1 str &&
[ "$str" ];do
while IFS= read -d '' -rsn 1 -t .02 char
do str+="$char"
done
if [ "$str" ] ;then
read -a req <<<"$str"
echo $req
mplayer $req
fi
done
First read will determine if something is comming or else end loop.
Second loop with very short timeout will read dropped URL as a single string
read -a req will split string to consider only 1st part

bash save last user input value permanently in the script itself

Is it possible to save last entered value of a variable by the user in the bash script itself so that I reuse value the next time while executing again?.
Eg:
#!/bin/bash
if [ -d "/opt/test" ]; then
echo "Enter path:"
read path
p=$path
else
.....
........
fi
The above script is just a sample example I wanted to give(which may be wrong), is it possible if I want to save the value of p permanently in the script itself to so that I use it somewhere later in the script even when the script is re-executed?.
EDIT:
I am already using sed to overwrite the lines in the script while executing, this method works but this is not at all good practice as said. Replacing the lines in the same file as said in the below answer is much better than what I am using like the one below:
...
....
PATH=""; #This is line no 7
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )";
name="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")";
...
if [ condition ]
fi
path=$path
sed -i '7s|.*|PATH='$path';|' $DIR/$name;
Someting like this should do the asked stuff :
#!/bin/bash
ENTERED_PATH=""
if [ "$ENTERED_PATH" = "" ]; then
echo "Enter path"
read path
ENTERED_PATH=$path
sed -i 's/ENTERED_PATH=""/ENTERED_PATH='$path'/g' $0
fi
This script will ask user a path only if not previously ENTERED_PATH were defined, and store it directly into the current file with the sed line.
Maybe a safer way to do this, would be to write a config file somewhere with the data you want to save and source it . data.saved at the begining of your script.
In the script itself? Yes with sed but it's not advisable.
#!/bin/bash
test='0'
echo "test currently is: $test";
test=`expr $test + 1`
echo "changing test to: $test"
sed -i "s/test='[0-9]*'/test='$test'/" $0
Preferable method:
Try saving the value in a seperate file you can easily do a
myvar=`cat varfile.txt`
And whatever was in the file is not in your variable.
I would suggest using the /tmp/ dir to store the file in.
Another option would be to save the value as an extended attribute attached to the script file. This has many of the same problems as editing the script's contents (permissions issues, weird for multiple users, etc) plus a few of its own (not supported on all filesystems...), but IMHO it's not quite as ugly as rewriting the script itself (a config file really is a better option).
I don't use Linux, but I think the relevant commands would be something like this:
path="$(getfattr --only-values -n "user.saved_path" "${BASH_SOURCE[0]}")"
if [[ -z "$path" ]]; then
read -p "Enter path:" path
setfattr -n "user.saved_path" -v "$path" "${BASH_SOURCE[0]}"
fi

Resources