The goal here is when parameters $AutoBasher is set read from file line by line then take that variable and add it to a curl command. I also tried to have it when the parameters is set then run this command, if not then this command. Id like the script to run a one automated command, if not then run command with $URL.
AutoBasher()
{
if [[ -z "$AutoBasher" ]]; then
echo ''
else
for FileLine in $AutoBasher; do
while IFS= `read -r Line`; do
echo ${Line}
done < "FileLine"
done < "$AutoBasher"
fi
}
curl $(AutoBasher)
Related
I'm downloading a file from the web and I would like to redirect the file to stdout only if there is something printed to stdout, if not I would like to skip the redirection. This is because I have an if..then..else statement as follows:
if ! [[ -f data/worldcitiespop.csv ]]; then curl -L https://burntsushi.net/stuff/worldcitiespop.csv ; fi > data/worldcitiespop.csv 2> log
In case data/worldcitiespop.csv already exists and if i run this again the output will be empty. I don't want that, I want to leave it populated.
You can store curl command output in a variable and check if there is a non-whitespace character in that variable before writing that variable content to output file:
if ! [[ -f data/worldcitiespop.csv ]]; then
out=$(curl -L https://burntsushi.net/stuff/worldcitiespop.csv 2>log)
[[ $out = *[![:space:]]* ]] && echo "$out" > data/worldcitiespop.csv
fi >
I have a shell script that uses the sed command to transform an input file to a new output file, this script works when I call :
./sed_command.sh input_file > output_file
here is my script :
#!/usr/bin/env sh
while read line
do
# Split each line based on ; separator
transposed=$(echo "$line" | sed -e "s/;/\\n/g")
res=$(echo "$transposed" | sed '/${GDATEF(\([^,]*\),ddMMyyyy)}/{
# Split the string in two part
s//\1/g
# # parse the input for GNU date input format
s/D/ day/g
# Handle shell quoting
'"s/'/\\''\\'/"'
# pass and execute date
s/.*/date -d "now "'\''&'\'' +%d%m%Y/e
}')
oneline=$(echo "$res" | sed -z "s/\n/;/g" | sed 's/.$//')
echo $oneline
done < $1
Now I need to call that script inside a double loop that browse all directories in a folder :
cd /etc/newman/Newman
for team in *;do
if [ -d "$team" ]; then
echo "team=$team"
cd $team
for scope in *;do
if [ -d "$scope" ]; then
echo "scope=$scope"
CSV_FILE=$(ls /etc/newman/Newman/$team/$scope/*.csv -1 || true)
echo "Transforming : ${CSV_FILE}"
if [ ! -z "${CSV_FILE}" ] ; then sh sed_command.sh ${CSV_FILE} > ${CSV_FILE}_Newman; else echo "No CSV files to transform"; fi
fi
done
cd ..
fi
done
I have tested the second script looping works fine the only issue is when I call sed_command.sh inside the second script I get theses two errors :
: not found.sh: line 2:
sed_command.sh: line 19: syntax error: unexpected "done" (expecting "do")
I guess redirection does not work the same way inside a loop? thanks for help
Running another script in bash script while loop runs but the loop breaks!
N.B. The script I mentioned just loops over files in current directory and just run mpirun.
Here's my bash script:
#!/bin/bash
np="$1"
bin="$2"
ref="$3"
query="$4"
word_size="$5"
i=1;
input="$query"
while read line; do
echo $line
if [[ "${line:0:1}" == ">" ]] ; then
header="$line"
echo "$header" >> seq_"${i}".fasta
else
seq="$line"
echo "$seq" >> seq_"${i}".fasta
if ! (( i % 5)) ; then
./run.sh $np $bin $ref $word_size
^^^^^^^^
#for filename in *.fasta; do
# mpirun -np "${np}" "${bin}" -d "${ref}" -ql "${filename}" -k "${word_size}" -b > log
# rm $filename
#done
fi
((i++))
fi
done < $input
The problem is that your run.sh script is passing no parameters to mpirun. That script passes the variables ${np} ${bin} ${ref} ${filename} ${word_size} to mpirun, but those variables are local to your main script and are undefined in run.sh. You could export those variables in the main script so that they are available to all child processes, but a better solution would be to use positional parameters in run.sh:
for filename in *.fasta; do
mpirun -np "${1}" "${2}" -d "${3}" -ql "${4}" -k "${5}" -b > log
rm $filename
done
I don't know about mpirun, but if you have anything inside your loop that reads from stdin, the loop will break.
I have a heredoc that needs to call existing variables from the main script, and set its own variables to use later. Something like this:
count=0
ssh $other_host <<ENDSSH
if [[ "${count}" == "0" ]]; then
output="string1"
else
output="string2"
fi
echo output
ENDSSH
That doesn't work because 'output' doesn't get set to anything.
I tried using the solution from this question:
count=0
ssh $other_host << \ENDSSH
if [[ "${count}" == "0" ]]; then
output="string1"
else
output="string2"
fi
echo output
ENDSSH
It didn't work either. $output got set to "string2" because $count wasn't expanded.
How can I use a heredoc that expands variables from the parent script, and sets its own variables?
You can use:
count=0
ssh -t -t "$other_host" << ENDSSH
if [[ "${count}" == "0" ]]; then
output="string1"
else
output="string2"
fi
echo "\$output"
exit
ENDSSH
We use \$output so that it is expanded on remote host not locally.
It is better not to use stdin (such as by using here-docs) to pass commands to ssh.
If you use a command-line argument to pass your shell commands instead, you can better separate what is expanded locally and what will be executed remotely:
# Use a *literal* here-doc to read the script into a *variable*.
# Note how the script references parameter $1 instead of
# local variable $count.
read -d '' -r script <<'EOF'
[[ $1 == '0' ]] && output='zero' || output='nonzero'
echo "$output"
EOF
# The variable whose value to pass as a parameter.
# With value 0, the script will echo 'zero', otherwise 'nonzero'.
count=0
# Use `set -- '$<local-var>'...;` to pass the local variables as
# positional parameters, followed by the script code.
ssh localhost "set -- '$count'; $script"
You can escape the variables as #anubhava said, or, if you get too much variables for the escaping, you can do it in two steps:
# prepare the part which should not be expanded
# note the quoted 'EOF'
read -r -d '' commands <<'EOF'
if [[ "$count" == "0" ]]; then
echo "$count - $HOME"
else
echo "$count - $PATH"
fi
EOF
localcount=1
#use the unquoted ENDSSH
ssh me#nox.local <<ENDSSH
count=$localcount # count=1
#here will be inserted the above prepared commands
$commands
ENDSSH
will print something like:
1 - /usr/bin:/bin:/usr/sbin:/sbin
I am trying to execute a hallo_word.sh that is stored at ~/bin from this script that is stored at my ~/Desktop. I have made both scripts executable. But all the time I get the problem message. Any ideas?
#!/bin/sh
clear
dir="$PATH"
read -p "which file you want to execute" fl
echo ""
for fl in $dir
do
if [ -x "$fl" ]
then
echo "executing=====>"
./$fl
else
echo "Problem"
fi
done
This line has two problems:
for fl in $dir
$PATH is colon separated, but for expects whitespace separated values. You can change that by setting the IFS variable. This changes the FIELD SEPARATOR used by tools like for and awk.
$fl contains the name of the file you want to execute, but you overwrite its value with the contents of $dir.
Fixed:
#!/bin/sh
clear
read -p "which file you want to execute" file
echo
IFS=:
for dir in $PATH ; do
if [ -x "$dir/$file" ]
then
echo "executing $dir/$file"
exec "$dir/$file"
fi
done
echo "Problem"
You could also be lazy and let a subshell handle it.
PATH=(whatever) bash command -v my_command
if [ $? -ne 0 ]; then
# Problem, could not be found.
else
# No problem
fi
There is no need to over-complicate things.
command(1) is a builtin command that allows you to check if a command exists.
The PATH value contains all the directories in which executable files can be run without explicit qualification. So you can just call the command directly.
#!/bin/sh
clear
# r for raw input, e to use readline, add a space for clarity
read -rep "Which file you want to execute? " fl || exit 1
echo ""
"$fl" || { echo "Problem" ; exit 1 ; }
I quote the name as it could have spaces.
To test if the command exists before execution use type -p
#!/bin/sh
clear
# r for raw input, e to use readline, add a space for clarity
read -rep "Which file you want to execute? " fl || exit 1
echo ""
type -p "$fq" >/dev/null || exit 1
"$fl" || { echo "Problem" ; exit 1 ; }