Automated script install using bash [closed] - linux

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 3 years ago.
Improve this question
I'm trying to script install the below, how can I answer "y" at the prompt within the command
wget -O - mic.raspiaudio.com | sudo bash
I have tried the usual but this wont work
echo "y" | wget -O - mic.raspiaudio.com | sudo bash

Disclaimer: The solution below works for script that have a non-interactive switch.
I believe the echo won't work on this because it's not writing to the /dev/tty that the bash spawned. You can do it using the default feature bash provides.
From the man page:
-c If the -c option is present, then commands are read from the first
non-option argument command_string. If there are arguments after the
command_string, the first argument is assigned to $0 and any remaining
arguments are assigned to the positional parameters.
If you use -c option with bash, you can supply args to script that will run and those will be placed as mentioned in the man page. eg:
bash -c "script" "arg0" "arg1" .... The arg0 will be placed in $0 and arg1 will be placed in $1 and so on.
Now, I don't know if this can be generalized, but this solution will only work if there is a non-interactive mode in the script.
If you see the script it has the following function:
FORCE=$1
confirm() {
if [ "$FORCE" == '-y' ]; then
true
else
read -r -p "$1 [y/N] " response < /dev/tty
if [[ $response =~ ^(yes|y|Y)$ ]]; then
true
else
false
fi
fi
}
And is used as :
if confirm "Do you wish to continue"
then
echo "You are good to go"
fi
So, if we can set the $1 to "-y" it won't ask for a confirmation, We will try to do that same by:
$ bash -c "$( wget -qO - mic.raspiaudio.com)" "dummy" "-y"
This should work for the script, provided it does not have any other interactive options. I have not tested the original script by my own minimal script and it seems to work. eg:
$ bash -c "$(wget -qO - localhost:8080/test.sh)" "dummy" -y
You are good to go
$ bash -c "$(wget -qO - localhost:8080/test.sh)"
Do you wish to continue [y/N] y
You are good to go

Related

Is it possible to use the source command multiple times on different files? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 12 months ago.
Improve this question
I currently try to write a bash script which should help me to automate the virtual enviroments in python alittle bit.
The problem is that it seems that I am not able to source twice. (Sourcing in a bash script another bash script).
These are the files which I use:
#!/bin/bash
# Call this file with . filename or source filename to run it in the current bash
if [ "$#" -eq 1 ]
then
if [ "$1" == "install" ]
then
pip install kivy[base]
# Install Kivy and some examples
#python -m pip install kivy[base] kivy_examples
elif [ "$2" == "start" ]
then
source ../virtualEnviroment.sh Kivy
fi
fi
virtualEnviroment.sh:
#!/bin/bash
# Call this file with . filename or source filename to run it in the current bash
ENVIROMENTNAME=$1
DIR=$1
(return 0 2>/dev/null) && sourced=1 || sourced=0
if [ "$#" -ne 1 ]
then
echo Missing enviromentname
else
if [ "$sourced" -eq 1 ]
then
if [ -d "$DIR" ]
then
echo Using existing enviroment $ENVIROMENTNAME
source "$ENVIROMENTNAME"/bin/activate
else
echo Creating new enviroment $ENVIROMENTNAME
python3 -m virtualenv "$ENVIROMENTNAME"
source "$ENVIROMENTNAME"/bin/activate
fi
else
echo Please use . $0 or source $0
fi
fi
Did I do something wrong, or is it normal that I only can source one time?
(Does it try to use the bash environment of the first bash script, but since it is already sourced, it can not use the sourced bash environment and use the unsourced bash environment of the first bash script?)
It seems I just forgot to add another source to the bash script to source the second bash file too.

Passing static variables to GNU Parallel [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
In a bash script I am trying to pass multiple distinct fastq files and several user-provided static variables to GNU Parallel. I can't hardcode the static variables because while they do not change within the script, they are set by the user and are variable between uses. I have tried a few different ways but get an error argument -b/--bin: expected one argument
Attempt 1:
binSize="10000"
outputDir="output"
errors="1"
minReads="10"
ls fastq_F* | parallel "python myscript.py -f split_fastq_F{} -b $binSize -o $outputDir -e $errors -p -t $minReads"
Attempt 2:
my_func() {
python InDevOptimizations/DemultiplexUsingBarcodes_New_V1.py \
-f split_fastq_F$1 \
-b $binSize \
-o $outputDir \
-e $errors \
-p \
-t $minReads
}
export -f my_func
ls fastq_F* | parallel my_func
It seems clear that I am not correctly passing the static variables... but I can't seem to grasp what the correct way to do this is.
Always try --dr when GNU Parallel does not do what you expect.
binSize="10000"
outputDir="output"
errors="1"
minReads="10"
ls fastq_F* | parallel --dr "python myscript.py -f split_fastq_F{} -b $binSize -o $outputDir -e $errors -p -t $minReads"
You are using " and not ' so the variables should be substituted by the shell before GNU Parallel starts.
If the commands are run locally (i.e. not remote) you can use export VARIABLE.
If run on remote servers, use env_parallel:
env_parallel --session
alias myecho='echo aliases'
env_parallel -S server myecho ::: work
myfunc() { echo functions $*; }
env_parallel -S server myfunc ::: work
myvar=variables
env_parallel -S server echo '$myvar' ::: work
myarray=(arrays work, too)
env_parallel -k -S server echo '${myarray[{}]}' ::: 0 1 2
env_parallel --end-session

(Linux-Bash) Create an account for each user and add the user to its group from a text file [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have a username.txt which contains their username and specific group. As of right now i'm trying to create a bash script which allows me to create an account for each user and add the user to its group in one command.
this is currently my failed bash script(i know pretty much everything is wrong but i hope you guys got a clear idea on it):
#!/bin/bash
sudo addgroup staff
sudo addgroup visitors
username="username.txt"
while read line; do
sudo useradd $-Eo '^[^,]+' $username;
if [grep staff $username]; then
sudo usermod -a -G staff
else
sudo usermod -a -G visitors
done < $username
This is what is inside my username.txt file:
ellipsiscoterie,visitor
magnetcommonest,visitor
belateddefensive,staff
bobstercaramelize,staff
Let's go through your script.
#!/bin/bash
sudo addgroup staff
sudo addgroup visitors
username="username.txt"
OK. There is some debate about using sudo in scripts, but I'm not against it.
while read line; do
You read the line from STDIN, which is your input file. The variable line contains ellipsiscoterie,visitor in the first iteration.
sudo useradd $-Eo '^[^,]+' $username;
$- prints The current set of options in your current shell. It will produce something like himBH. The next argument seems a regular expression, and the last argument is the filename that you use. So the command here is:
sudo useradd himBHEo '^[^,]+' username.txt
Hint: if you are unsure of the arguments, check with an echo (echo $-Eo '^[^,]+' $username) before you add them to a sudo-ed command.
This is not what you want. First, you probably want to use the variable line instead of username. Why would you otherwise loop through that file?
Second, read-up on variable expansion in bash. For now, try:
line=ellipsiscoterie,visitor
echo ${line%,*}
echo ${line#*,}
So the line would probably need to be:
sudo useradd ${line%,*}
if [grep staff $username]; then
This is wrong in almost everything.
the [ and ] require spaces to set them apart
but you dont want to do a test, you want to see if the grep succeeds, so the [ and ] are not needed anyway
you are again using the complete file. So the grep succeeds if there is any line with staff in it; even if the username would be johnfalstaff
What you really want to know is if the second column in your line is staff, so:
if [ "${line#*,}" = "staff" ] ; then
sudo usermod -a -G staff
else
sudo usermod -a -G visitors
So, where is the fi that closes the if statement?
done < $username
Also, quote the filename: done < "$username"
You can use awk to write it in one line. In this case, awk splits each row into different columns and you can access each field separately.
awk -F "," '{ if(system("grep -q -E "$2" /etc/group") != 0 ){system("groupadd "$2)}; system("useradd "$1" -G "$2)}' username.txt
The first argument (-F ",") defines the field-separator, but it could be also something else e.g. ";" or "/"
The part if(system("grep -q -E "$2" /etc/group") != 0 ) verifies if the group exist and if not, the part {system("groupadd "$2)} creates the group before the next command system("useradd "$1" -G "$2) creates the user and adds it to the group $2.
It's possible to simplify the command to remove the if part, but then you will get a warning message that the user already exists.
awk -F "," '{ system("groupadd "$2); system("useradd "$1" -G "$2)}' username.txt
groupadd: group 'visitor' already exists
groupadd: group 'staff' already exists
btw: the part system executes just an operating system command
The newusers command allows you to configure users from a file in batch:
https://www.man7.org/linux/man-pages/man8/newusers.8.html

How to write a "bash script.sh argument " [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
hi can someone help me with this.
How to Write a script that takes in as argument a filename and displays its modification date and time in this way exactly :
[user#localhost...]$ bash script.sh temp.txt
the file temp.txt was modified on May 1 20:20
And then modify that script in such a way that it lists the modification dates for directories whose names contain a given pattern in this way exactly :
[user#local....]$ bash script.sh testRegex Pub
the file testRegex was modified on May 1 20:22
the directory /home/user/Public was modified on Dec 26 08:00
the directory /home/user/Pubs. was modified on May 2 20:00
please help I need to answer this fast
Thanks
This is pretty simple to do actually. You should read up on the stat command as #John Bollinger said. I also used the date command to format the date. You can read up on taking arguments for a script here
Combining all of this would give -
#!/bin/bash
filename=$1;
dirname=$2;
file_mod_date=`date -d #$( stat -c %Y $1 ) +%m" "%B" "%H:%M`;
echo "The file ${filename} was modified on ${file_mod_date}";
if [ "$2" == "" ]; then
exit 1;
else
for i in /home/user/*${dirname}*/; do
dir_mod_date=`date -d #$( stat -c %Y $i ) +%m" "%B" "%H:%M`;
echo "The directory ${i} was modified on ${dir_mod_date}";
done
fi
A good way to do this is with passing options and values:
For example:
file_name=""
help_message="To use this script type script.sh --file /path/to/file.txt"
# -- Get input options (if any)
while [[ $# > 0 ]] ;do
key="$1"
case ${key,,} in
-f|--file)
file_name="${2,,}"
shift
;;
-h|--help)
echo -e "$help_message"
exit;
shift
;;
esac
shift
done
Call the script like this:
bash script.sh -f "temp.txt"
With regard to the "logic" of the script, you will have to figure that out ;-)

How can I show the wget progress bar only? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
For example:
wget http://somesite.com/TheFile.jpeg
downloading: TheFile.tar.gz ...
--09:30:42-- http://somesite.com/TheFile.jpeg
=> `/home/me/Downloads/TheFile.jpeg'
Resolving somesite.co... xxx.xxx.xxx.xxx.
Connecting to somesite.co|xxx.xxx.xxx.xxx|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1,614,820 (1.5M) [image/jpeg]
25% [======> ] 614,424 173.62K/s ETA 00:14
How can I get it to look like the following?
downloading: TheFile.jpeg ...
25% [======> ] 614,424 173.62K/s ETA 00:14
I know curl can do that. However, I need to get wget to do that job.
Use:
wget http://somesite.com/TheFile.jpeg -q --show-progress
-q: Turn off wget's output
--show-progress: Force wget to display the progress bar no matter what its verbosity level is set to
You can use the following filter:
progressfilt ()
{
local flag=false c count cr=$'\r' nl=$'\n'
while IFS='' read -d '' -rn 1 c
do
if $flag
then
printf '%s' "$c"
else
if [[ $c != $cr && $c != $nl ]]
then
count=0
else
((count++))
if ((count > 1))
then
flag=true
fi
fi
fi
done
}
Usage:
$ wget --progress=bar:force http://somesite.com/TheFile.jpeg 2>&1 | progressfilt
100%[======================================>] 15,790 48.8K/s in 0.3s
2011-01-13 22:09:59 (48.8 KB/s) - 'TheFile.jpeg' saved [15790/15790]
This function depends on a sequence of 0x0d0x0a0x0d0x0a0x0d being sent right before the progress bar is started. This behavior may be implementation dependent.
Run using these flags:
wget -q --show-progress --progress=bar:force 2>&1
You can use the follow option of tail:
wget somesite.com/TheFile.jpeg --progress=bar:force 2>&1 | tail -f -n +6
The +6 is to delete the first 6 lines. It may be different on your version of wget or your language.
You need to use --progress=bar:force otherwise wget switches to the dot type.
The downside is that the refreshing is less frequent than with wget (looks like every 2 seconds). The --sleep-interval option of tail seems to be meant just for that, but it didn't change anything for me.
The option --show-progress, as pointed out by others, is the best option, but it is available only since GNU wget 1.16, see Noteworthy changes in wget 1.16.
To be safe, we can first check if --show-progress is supported:
# set progress option accordingly
wget --help | grep -q '\--show-progress' && \
_PROGRESS_OPT="-q --show-progress" || _PROGRESS_OPT=""
wget $_PROGRESS_OPT ...
Maybe it's time to consider just using curl.
You can use standard options:
wget --progress=bar http://somesite.com/TheFile.jpeg
This is another example:
download() {
local url=$1
echo -n " "
wget --progress=dot $url 2>&1 | grep --line-buffered "%" | sed -u -e "s,\.,,g" | awk '{printf("\b\b\b\b%4s", $2)}'
echo -ne "\b\b\b\b"
echo " DONE"
}
Here is a solution that will show you a dot for each file (or line, for that matter). It is particularly useful if you are downloading with --recursive. This won't catch errors and may be slightly off if there are extra lines, but for general progress on a lot of files it is helpful:
wget -r -nv https://example.com/files/ | \
awk -v "ORS=" '{ print "."; fflush(); } END { print "\n" }'
This is not literally an answer but this snippet might also be helpful to some coming here for e.g. "zenity wget GUI":
LANG=C wget -O /dev/null --progress=bar:force:noscroll --limit-rate 5k http://nightly.altlinux.org/sisyphus/ChangeLog 2>&1 | stdbuf -i0 -o0 -e0 tr '>' '\n' | stdbuf -i0 -o0 -e0 sed -rn 's/^.*\<([0-9]+)%\[.*$/\1/p' | zenity --progress --auto-close
What was crucial for me is stdbuf(1).

Resources