Capturing multiple line output into a Bash variable with busybox sh - sh

I'm trying to convert a Debian Bash script into a linux Busybox sh script. I'm stuck trying to convert the following command:
read -r -d '' MESSAGE << EOM
Return code: $retn_code
Start of backup: $DATESTART
End of backup: $DATEEND
$(df -h | grep '/share/USB')
EOM
The problem is with the -d option of read that is not available with Busybox. How can I set a variable ($MESSAGE in this case) to a string with multiple lines that includes values from other variables?
The output MESSAGE is going in a log file and in a message sent by sendmail:
echo "RESULTS: $MESSAGE" >> $LOGFILE
sendmail -S smtp.server.com -f "$FROM" "$RECIPIENTS" <<EOF
subject:$SUBJECT
from:$FROM
$MESSAGE
EOF

Simplest answer is not to use read.
MESSAGE=$(cat <<EOM
Return code: $retn_code
Start of backup: $DATESTART
End of backup: $DATEEND
$(df -h | grep '/share/USB')
EOM
)
MESSAGE=$( printf "%s\n%s\n%s\n%s\n" \
"Return code: $retn_code" \
"Start of backup: $DATESTART" \
"End of backup: $DATEEND" \
"$(df -h | grep '/share/USB')" \
)

You don't need a special command in any shell; just a regular assignment.
message="Return code: $retn_code
Start of backup: $DATESTART
End of backup: $DATEEND
$(df -h | grep '/share/USB')
"

Related

radare2 -c and -i options do not execute more than one command

All commands below do not execute psz # [rax]. Why?
script=$(mktemp)
cat > $script << EOF
dcu 0x00404d29
psz # [rax]
EOF
r2 -d -R input="a" -i $script exatlon_unpacked
r2 -d -R input="a" -c "dcu 0x00404d29; psz # [rax]" exatlon_unpacked
r2 -d -R input="a" -c 'dcu 0x00404d29' -c 'psz # [rax]' exatlon_unpacked

problems while reading log file with tail -n0 -F

i am monitoring the asterisk log file for peers that get offline.
the if part is working correct, but the sed command is not executed in the else part, although the echo command works. What do i need to change
tail -n0 -F /var/log/asterisk/messages | \
while read LINE
do
if echo "$LINE" | /bin/grep -q "is now UNREACHABLE!"
then
EXTEN=$(echo $LINE | /bin/grep -o -P "(?<=\').*(?=\')")
echo "$EXTEN is now UNREACHABLE!"
CALLERID=$(/bin/sed -n '/^\['"$EXTEN"'\]/,/^\[.*\]/{/^callerid*/p}' "$SIP" | /usr/bin/awk -F'=' '{ print $2 }')
if .......
then
.......
fi
elif echo "$LINE" | /bin/grep -q "is now REACHABLE!"
then
EXTEN=$(echo $LINE | /bin/grep -o -P "(?<=\').*(?=\')")
echo "$EXTEN is now REACHABLE!"
if /bin/grep -qi "^$EXTEN;" $OFFLINE; then
/bin/sed -i '/^$EXTEN;/d' $OFFLINE
fi
fi
done
You have a quoting problem - you've used single quotes when the string includes a shell variable:
if /bin/grep -qi "^$EXTEN;" $OFFLINE; then
/bin/sed -i '/^$EXTEN;/d' $OFFLINE
fi
Try using double quotes instead:
if /bin/grep -qi "^$EXTEN;" $OFFLINE; then
/bin/sed -i "/^$EXTEN;/d" $OFFLINE
fi

sed - Separate quotes and arguments

So, I'm trying to get a script I'm working on to run another script in different directories with different arguments as defined in a text file.
Here's part of my code:
for bline in $(cat "$file"); do
lindir=$()
linarg=$()
echo "dir: ${lindir}"
echo "arg: ${linarg}"
done
Let's say I have a line in file that says this:
"./puppies" -c=1 -u=0 -b=1
How can I get an output of ./puppies for lindir and an output of -c=1 -u=0 -b=1 for linarg?
lindir="$( cut -d ' ' -f 1 <<<"$bline" )"
linarg="$( cut -d ' ' -f 2- <<<"$bline" )"
That is
while read -r bline; do
lindir="$( cut -d ' ' -f 1 <<<"$bline" )"
linarg="$( cut -d ' ' -f 2- <<<"$bline" )"
printf "dir: %s\n" "$lindir"
printf "arg: %s\n" "$linarg"
done <"$file"
If you're in a shell that doesn't understand "here-strings":
lindir="$( printf "%s" "$bline" | cut -d ' ' -f 1 )"
linarg="$( printf "%s" "$bline" | cut -d ' ' -f 2- )"

NetworkManager dispatcher script

scripts in /etc/NetworkManager/dispatcher.d will got exec and parameters will be passed to the scripts by NetworkManager.
One of my laptop BIOS is malfunctioning, I have to manually sync the time, and do system upgrade BTW. I am working with a script to automate this task.
Here's the script:
#!/bin/sh
IF=$1
STATUS=$2
if [ "$STATUS"x != 'up'x -o "$(date +%Y)" -gt "2012" ] ;then
exit
fi
logger "==$0=="
wait_for_process(){
PNAME=$1
PID=`pgrep $PNAME`
while [ -z "$PID" ];do
logger "waiting $1 running for another 3 sec.."
sleep 3;
PID=`pgrep $PNAME`
done
logger "$1 is running!"
}
wait_for_process nm-applet
wait_for_process lxpanel
export DISPLAY=$(echo $DISPLAY | cut -c -2)
if [ -z $DISPLAY ];then
export DISPLAY=:0
fi
#below cmd will yield null string for $user
user=$(who | grep "$DISPLAY" | awk '{print $1}' | tail -n1)
#so I have to hardcode the user name:(
user=xxx
export XAUTHORITY="/home/$user/.Xauthority"
logger "Display $DISPLAY user $user"
su $user -c "xterm -e 'sudo /usr/bin/ntpd -qdg && sudo yaourt -Syua' &" || logger "cannot run xterm"
(the script is invoked before x window, run as root)
user=$(who | grep "$DISPLAY" | awk '{print $1}' | tail -n1) cannot find the login user name. But it works in xterm.
Can someone help?
I am using archlinux i686 + openbox + lxpanel
edit:
I want to find the real login user name, while the script is run by root.
Are you looking for the name of the user running the script? How about:
user=$( id -un )

get list of sections from ini-file using shell (sed/awk)

I want to create a var from the section names of an ini file like:
[foo]
; ...
[bar]
; ...
[baz:bar]
;...
now I need a var like
SECTIONS="foo bar baz"
thanks in advance
One line solution could be:
export SECTIONS=`grep "^\[" test.ini |sort -u | xargs | tr '\[' ' ' | tr '\]' ' ' `
SECTIONS=$(crudini --get your.ini | sed 's/:.*//')
I'm now using this construct, don't need to know if a section exists. just read it, if it's empty it does not exist.
INI_FILE=test.ini
function ini_get
{
eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
-e 's/;.*$//' \
-e 's/[[:space:]]*$//' \
-e 's/^[[:space:]]*//' \
-e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" \
< $INI_FILE \
| sed -n -e "/^\[$1\]/,/^\s*\[/{/^[^;].*\=.*/p;}"
echo ${!2}
}
IP=$(ini_get 50001 ip)
PORT=$(ini_get 50001 port)
echo $IP:$PORT