Combine & with && shell - linux

I have this shell script in a php file:
[ ! -e "dsaasdas3efsdgadd345y5erhaha45_temp" ] && touch dsaasdas3efsdgadd345y5erhaha45_temp && wget http://localmyurltofunction?id=100 -O ./images/100 > /dev/null 2>&1 && rm dsaasdas3efsdgadd345y5erhaha45_temp &
I tested that in shell without the last & and it works great, but when I add the last & won't run, returning 1. I need a way to combine && with my &, I use that & because I want this process to run in background on a separate fork compared to my script.

You probably want to run the entire list in the background, not just the rm command.
( [ ! -e foo ] && touch foo && wget ... && rm foo ) &

Related

Can I combine a long chain of sed commands into something shorter?

i successfully wrote a long line that works well for my usage.
it get a file, and format the text to be as i want.
is it possible to make it shorter ?
wget http://user:password#192.168.1.100/details.cgx \
&& sed "s/value/\n/g" details.cgx >> step1 \
&& sed "s/text/</g" step1 >> step2 \
&& sed "s/id/</g" step2 >> step3 \
&& tr -d '<>/' < step3 >> step4 \
&& sed "s/formFanLevel/FanLevel/g" step4 >> step5 \
&& sed '123,155d' step5 >> step6 \
&& sed '79,120d' step6 >> step7 \
&& sed '57,66d' step7 >> step8 \
&& sed '47,48d' step8 >> step9 \
&& sed '37,44d' step9 >> step10 \
&& sed '13,26d' step10 >> VMCDF.txt \
&& rm step* && rm details.cgx
I think you want this:
wget -O- http://user:password#192.168.1.100/details.cgx | sed -E '
s/value/\n/g
s/text|id/</g
s,<>/,,g
s/form(FanLevel)/\1/g
' | sed '
13,26d
37,44d
47,48d
57,66d
79,120d
123,155d
' > VMCDF.txt
A good start would be to learn how the pipe command (|) can be used to pass the output from one program as input to the next - this would remove the need to create, reference and clean up all the intermediate files (step1 .. step10) from your command line.
You can write a shell script that can apply the same command chain to any file, then use the script instead of typing all these lines.
If, though unlikely, you always use the same file, just make an alias for it by giving a name to the command chain, eg:
alias wgetsed='wget http://user:password#192.168.1.100/details.cgx \
&& sed "s/value/\n/g" details.cgx >> step1 \
&& sed "s/text/</g" step1 >> step2 \
...
&& rm step* && rm details.cgx'
You then add the code above to ~/.bash_rc to make it permanent for your user account.

If else with rm Shell linux

I need help whith my problem.
I need make a shell script...
this it's my idea
if [ rm -r -f /directorie ]; then
code
else
code
fi
...
how I can?
dir=/directory
test -d "${dir}" && rm -rf "${dir}" && ! test -d "${dir}" && echo OK || echo NOK
This code may achieve what you want:
#!/bin/bash
rm -r /directorie > /dev/null 2>&1; rc="$?"
if [ "$rc" -eq "0" ]; then
# code here
else
# code here
fi
Note: rm -rf /directorie (with the option f) would always return a return code = 0 (true), thus it is not suited for an if test.
Edit: this answer can be condensed into a bash one-liner:
rm -r /home/owner/scripts > /dev/null 2>&1 && code here (true) || code here (false)

Linux difference between when to use parentheses

Why do I get extra empty line when running 2). To me 1 is like 2. So why the extra line in 2)?
1)
export p1=$(cd $(dirname $0) && pwd)
# ^
echo p1
2)
export p2=$(cd $(dirname $0)) && pwd
# ^
echo p2
$echo $0
/bin/bash
$ echo $(cd $(dirname $0) && pwd)
/bin
$ echo $(cd $(dirname $0)) && pwd
/home/user
$
In the 1st expression it becomes echo $(cd /bin && pwd). Therefore the inner 2 commands execute in a subshell and return back the pwd value which is then echoed.
In the 2nd expression it gets reduced to echo $(cd /bin) && pwd. Therefore only the cd command executes in a subshell and returns nothing to echo (hence by default echo just prints an empty line). Since echo ran successfully(exit code=0) && results in true and pwd cmd is run in current shell and pwd gets printed
p1 captures the output of cd (empty) and pwd.
p2 only captures the output of cd, and then runs pwd without redirection.
echo p1 prints a literal p1 (with a newline). I guess you didn't actually copy-paste from your terminal, but instead typed in some thing else.
peter#tesla:~$ export p2=$(true) && pwd
/home/peter
peter#tesla:~$ echo "x${p2}x"
xx
cd in a subshell doesn't affect the parent shell's pwd, so I just substituted the true command to make it more readable.

What is the difference between these two commands

I have the following variables set in a script.
SU="/bin/su -s /bin/sh
WSO2_SCRIPT="JAVA_HOME=$JAVA_HOME /opt/autopilot/wso2is/bin/wso2server.sh"
WSO2_USER=autoplt
This part of the script is of concern:
if [ "$RETVAL" -eq "0" ]; then
if [ "$(whoami)" != "${WSO2_USER}" ]; then
$SU - $WSO2_USER -c "${WSO2_SCRIPT} start" >> ${WSO2_LOG} 2>&1 || RETVAL="4"
else
${WSO2_SCRIPT} start >> ${WSO2_LOG} 2>&1 || RETVAL="4"
fi
fi
If I am root, then the following command gets executed:
/bin/su -s /bin/sh - autoplt -c 'JAVA_HOME=/usr/java/latest /opt/autopilot/wso2is/bin/wso2server.sh start'
and
RETVAL
will get evaluated to 0.
When I am user autoplt, the following command gets executed:
JAVA_HOME=/usr/java/latest /opt/autopilot/wso2is/bin/wso2server.sh start
However
RETVAL
will get evaluated to 4?
Are they not the same commands? Shouldn't RETVAL be 0 in each case?
The command gets executed successfully when I run it in the shell as autoplt user.
Therefore is there something wrong with the way I have written it?
the double pipe || used in lines :
$SU - $WSO2_USER -c "${WSO2_SCRIPT} start" >> ${WSO2_LOG} 2>&1 || RETVAL="4"
${WSO2_SCRIPT} start >> ${WSO2_LOG} 2>&1 || RETVAL="4"
means if the first command succeed, then the second will not be executed
It means when running as root, it succeed then no change to RETVAL
and as a user, if fails so change RETVAL to 4

Redirecting vcftools file in linux - tips

Here is the code that gets the VCF file from a specific region using tabix and then filters it for specific (european) population using 'keep' option from vcftools.
####select specific population
if [ "$POP_FILE" != "" ]; then
vcftools --vcf temp.vcf --keep $POP_FILE --recode --recode-INFO-all > temp2.vcf 2> /dev/null
else
cp -f temp.vcf temp2.vcf
fi
PROBLEM: it creates the recode.vcf file but then the redirection is not happening as the temp2 file is empty
I would avoid vcftools and use bcftools (https://github.com/samtools/bcftools) instead:
if [ "$POP_FILE" != "" ]; then
bcftools view temp.vcf -S $POP_FILE -o temp2.vcf
else
cp -f temp.vcf temp2.vcf
fi
To install bcftools:
git clone --branch=develop git://github.com/samtools/bcftools.git
git clone --branch=develop git://github.com/samtools/htslib.git
cd htslib && make && cd ..
cd bcftools && make && cd ..
sudo cp bcftools/bcftools /usr/local/bin/

Resources