ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I wrote a little Bash script called work. It uses a case statement for its main menu, listing several options. Option one is the function fam, fping asset monitor, a simple while loop that pings a list of IP addresses.
While I have the main menu of the work script open in terminator, I want to launch this while loop in a separate terminator window of a certain size. Is this possible?
Meanwhile, I copied the while loop (fam) to its own file in /usr/local/bin, and currently start fam with
fam() {
while true; do
tput clear
for ip in "${List1[@]}" "${List2[@]}"; do
# Lines in ovpnip.txt read AssetTag,IPAddress (1505,10.7.1.21)
# Remove all including & after comma, leaving Asset Tag, e.g., 1505
assettag=$(grep "$ip" <"$workdir"/ovpnip.txt | sed -e 's/,.*//')
if ! fping -c 2 "$ip" &>/dev/null; then
echo -e "\e[31m- DN "$assettag" \e[96m@ \e[31m"$ip" -\e[96m"
else
echo -e "\e[32m+ UP "$assettag" \e[96m@ \e[32m"$ip" +\e[96m"
fi
done
echo -e "\nLooping heartbeat in...\n"
for i in {9..1..1}; do
echo -ne " ...$i...\n" && sleep 1
done
done
}
Thanks!
Last edited by SoberPistachio; 04-29-2017 at 02:36 AM.
Reason: Clarification
i think your current solution is acceptable.
you could also try starting the new window from within the fam function:
Code:
fam() {
terminator -x sh -c 'while true; do
tput clear
for ip in "${List1[@]}" "${List2[@]}"; do
# Remove all including & after comma, leaving Asset Tag, e.g., 1085
assettag=$(grep "$ip" <"$workdir"/ovpnip.txt | sed -e 's/,.*//')
if ! fping -c 2 "$ip" &>/dev/null; then
echo -e "\e[31m- DN "$assettag" \e[96m@ \e[31m"$ip" -\e[96m"
else
echo -e "\e[32m+ UP "$assettag" \e[96m@ \e[32m"$ip" +\e[96m"
fi
done
echo -e "\nLooping heartbeat in...\n"
for i in {9..1..1}; do
echo -ne " ...$i...\n" && sleep 1
done
done'
}
not tested.
you will have to fix the single quotes inside the single-quoted script.
since ondoho's solution might cause some issues with quotes, I thought... maybe it can be done differently.
With a here-document; Due to not having a terminator here, I used konsole instead, but the idea remains; it kind of works too:
Code:
scrippie=$(cat <<_EOF
while true
do
printf "."
sleep 1
done
_EOF
)
konsole -e /bin/bash "${scrippie}"
and correcting for the internal single quotes yields
/usr/local/bin/work: line 81: syntax error near unexpected token `do'
/usr/local/bin/work: line 81: ` terminator -x sh -c while true; do'
I could have easily messed up the quoting. Will google more and keep trying.
Here is what I have at the moment for the heredoc, which does indeed work. Somewhat.
Code:
#!/usr/bin/env bash
list1=("10.7.1.45" "10.7.1.46" "10.7.1.47" "10.7.1.48")
list2=("10.7.1.31" "10.7.1.32" "10.7.1.33" "10.7.1.34" \
"10.7.1.35" "10.7.1.36" "10.7.1.37" "10.7.1.38")
workdir=$HOME/.work
scrippie=$(cat <<_EOF
while true; do
tput clear
for ip in "${list1[@]}" "${list2[@]}"; do
# Remove everything including and after the comma, leaving the Asset Tag, e.g., 1085
assettag=$(grep "$ip" <"$workdir"/ovpnip.txt | sed -e 's/,.*//')
if ! fping -c 2 "$ip" &>/dev/null; then
echo -e "\e[31m- DN "$assettag" \e[96m@ \e[31m"$ip" -\e[96m"
else
echo -e "\e[32m+ UP "$assettag" \e[96m@ \e[32m"$ip" +\e[96m"
fi
done
echo -e "\nLooping heartbeat in...\n"
for i in {9..1..1}; do
echo -ne " ...$i...\n" && sleep 1
done
done
_EOF
)
terminator -b --geometry=186x450 -x sh -c "${scrippie}"
The heredoc results in the following error, but opens a terminator window at the right size! None of the variables are expanding though, they are simply missing from the output. See the attached image. The sed part may be working I think (assettag=$(grep "$ip" <"$workdir"/ovpnip.txt | sed -e 's/,.*//'))...because the 3rd column on each line (1617, boipad (Bo's iPad)) and so on are proper Asset Tags.
Code:
** (terminator:14510): WARNING **: Binding '<Shift><Control><Alt>a' failed!
Unable to bind hide_window key, another instance/window has it.
PluginRegistry::load_plugins: Importing plugin __init__.py failed: 'module' object has no attribute 'AVAILABLE'
Using terminator -b --geometry=186x450 -e sh -c "${scrippie}" opens a window with a $ and a blinking cursor.
* Edit 2: Will keep reading and playing around until something sticks. Thanks again!
Last edited by SoberPistachio; 04-27-2017 at 06:45 PM.
Reason: Correcting mistakes
and correcting for the internal single quotes yields
/usr/local/bin/work: line 81: syntax error near unexpected token `do'
/usr/local/bin/work: line 81: ` terminator -x sh -c while true; do'
I could have easily messed up the quoting. Will google more and keep trying.
well show us the whole script, i'm sure it's fixable.
sed can usually use double quotes as well.
#!/bin/bash
# This script opens 4 terminal windows.
i="0"
while [ $i -lt 4 ]
do
xterm &
i=$[$i+1]
done
your while [ true ] ; do
try that ...
I do not know if you should pipe | that or not
wouldn't hurt to try. I'm signing off or I've a tried it before posting.. so I'll just leave you with that idea to try instead.
Code:
terminator -x sh -c | while [ true ] ;
do
..
..
...
done
#!/usr/bin/env bash
list1=("10.7.1.45" "10.7.1.46" "10.7.1.47" "10.7.1.48")
list2=("10.7.1.31" "10.7.1.32" "10.7.1.33" "10.7.1.34" \
"10.7.1.35" "10.7.1.36" "10.7.1.37" "10.7.1.38")
workdir=$HOME/.work
mainMenu() {
while true; do
echo -e "\n1. fping monitor"
echo "2. quit"
echo ""; read -p '>>> ' response
case $response in
1) terminator -b --geometry=186x450 -e sh -c "${fam}" ;;
2) exit 0 ;;
*) echo -e "\nInvalid option: "$response". Reloading...\n"; sleep 1; mainMenu ;;
esac
done
}
fam=$(cat <<_EOF
while true; do
tput clear
for ip in "${list1[@]}" "${list2[@]}"; do
assettag=$(grep "$ip" <"$workdir"/ovpnip.txt | sed -e 's/,.*//')
if ! fping -c 2 "$ip" &>/dev/null; then
echo -e "\e[31m- DN "$assettag" \e[96m@ \e[31m"$ip" -\e[96m"
else
echo -e "\e[32m+ UP "$assettag" \e[96m@ \e[32m"$ip" +\e[96m"
fi
done
echo -e "\nLooping heartbeat in...\n"
for i in {9..1..1}; do
echo -ne " ...$i...\n" && sleep 1
done
done
_EOF
)
mainMenu
Running this in terminator...
- Opens a new terminator window with a $ prompt and a blinking cursor
- The following error displays in the parent window:
Code:
** (terminator:29590): WARNING **: Binding '<Shift><Control><Alt>a' failed!
Unable to bind hide_window key, another instance/window has it.
PluginRegistry::load_plugins: Importing plugin __init__.py failed: 'module' object has no attribute 'AVAILABLE'
Changing mainMenu option 1 from -e sh -c to -x sh -c comes closest to the goal:
- The same bind hide_window key error displays in the parent terminal but
- A new terminator window opens
- The attached image in post #4 above shows what the new terminator window displays when using -x sh -c. Items in the 3rd column are asset tags.
Two other things with the here document that didn't work:
1. Modifying mainMenu option 1 to read -x /bin/bash "${fam}" instead of -x sh -c...
Same bind hide_window key error in the parent terminal
The new window opens and closes too fast to read
2. -e /bin/bash "${fam}" made terminator barf a wall of text all over the parent window. But expansion and sed appear to have worked.
Code:
Usage: terminator [options]
terminator: error: Additional unexpected arguments found: ['while true; do\n tput clear\n for ip in "10.7.1.45 10.7.1.46 10.7.1.47 10.7.1.48" "10.7.1.31 10.7.1.32 10.7.1.33 10.7.1.34 10.7.1.35 10.7.1.36 10.7.1.37 10.7.1.38"; do\n assettag=1615\n1617\nboipad\npi01\n1618\n1619\n1620\n1621\n1622\n1623\n1624\n1625\n if ! fping -c 2 "" &>/dev/null; then\n echo -e "\\e[31m- DN "" \\e[96m@ \\e[31m"" -\\e[96m"\n else\n echo -e "\\e[32m+ UP "" \\e[96m@ \\e[32m"" +\\e[96m"\n fi\n done\n echo -e "\\nLooping heartbeat in...\\n"\n for i in {9..1..1}; do\n echo -ne " ......\\n" && sleep 1\n done\ndone']
Non-heredoc method
Single quotes for sed were changed to double quotes.
Code:
#!/usr/bin/env bash
list1=("10.7.1.45" "10.7.1.46" "10.7.1.47" "10.7.1.48")
list2=("10.7.1.31" "10.7.1.32" "10.7.1.33" "10.7.1.34" \
"10.7.1.35" "10.7.1.36" "10.7.1.37" "10.7.1.38")
workdir=$HOME/.work
mainMenu() {
while true; do
echo -e "\n1. fping monitor"
echo "2. quit"
echo ""; read -p '>>> ' response
case $response in
1) fam ;;
2) exit 0 ;;
*) echo -e "\nInvalid option: "$response". Reloading...\n"; sleep 1; mainMenu ;;
esac
done
}
fam=() {
terminator -b --geometry=186x450 -x sh -c 'while true; do
tput clear
for ip in "${list1[@]}" "${list2[@]}"; do
assettag=$(grep "$ip" <"$workdir"/ovpnip.txt | sed -e "s/,.*//")
if ! fping -c 2 "$ip" &>/dev/null; then
echo -e "\e[31m- DN "$assettag" \e[96m@ \e[31m"$ip" -\e[96m"
else
echo -e "\e[32m+ UP "$assettag" \e[96m@ \e[32m"$ip" +\e[96m"
fi
done
echo -e "\nLooping heartbeat in...\n"
for i in {9..1..1}; do
echo -ne " ...$i...\n" && sleep 1
done
done'
}
mainMenu
- Prints the same bind hide_window key error
- New terminator window opens and closes too fast to see if it displays anything
The same results happen if -x sh -c is replaced with -e sh -c or -x /bin/bash.
Using -e /bin/bash summons wall barf. Unlike in the heredoc version of the script, it appears that neither expansion nor sed worked.
Code:
terminator: error: Additional unexpected arguments found: ['while true; do\n\t\ttput clear\n\t\tfor ip in "${list1[@]}" "${list2[@]}"; do\n\t\t\tassettag=$(grep "$ip" <"$workdir"/ovpnip.txt | sed -e "s/,.*//")\n\t\t\tif ! fping -c 2 "$ip" &>/dev/null; then\n echo -e "\\e[31m- DN "$assettag" \\e[96m@ \\e[31m"$ip" -\\e[96m"\n else\n echo -e "\\e[32m+ UP "$assettag" \\e[96m@ \\e[32m"$ip" +\\e[96m"\n\t\t\tfi\n\t\tdone\n\t\techo -e "\\nLooping heartbeat in...\\n"\n\t\tfor i in {9..1..1}; do\n\t\t\techo -ne " ...$i...\\n" && sleep 1\n\t\tdone\n\tdone']
Not quite there yet...
Last edited by SoberPistachio; 04-29-2017 at 03:53 AM.
Reason: Clarification
1) don't worry about the terminaltor keybind warning.
2) if you use the method i suggested, i think it doesn't know anything about the variables you use, i.e. list1, list2 and workdir, and therefore probably errors out.
you can pass them as command line options.
in post #1 you wrote that you had a working solution which had the script as a separate file.
i answered that that solution is acceptable imo.
you since edited post #1. please don't do that.
so, again: you had a working solution. i understand you weren't happy with it because it's somewhat inelegant?
1) Yes, warning not error, my mistake.
2) Yes, and many thanks!
I edited post #1 to include the comment that lines in ovpnip.txt read AssetTag,IPAddress, for a bit of clarification.
I guess I'm satisfied with the current solution, it does work after all. Just curious if there was a way to launch that function in a new terminator window from an existing session. Easy enough to do if the new window is a command + a few options, but I couldn't find examples of anything as lengthy as that while loop used in that way.
Edit: Piping terminator -b --geometry=186x450 -x /bin/bash | while true; do at the start of the function spawns a new window with the expected PS1 prompt, but the fam function runs inside the parent terminal.
Last edited by SoberPistachio; 04-29-2017 at 06:14 AM.
Reason: Piping test
if [[ -n "$DISPLAY" ]] && [[ -n "$WINDOWID" ]] ; then
PROGNAM="$(basename $0)"
ID="$(xprop -id "$WINDOWID" WM_NAME)"
ID="${ID##* }"
ID="${ID//\"/}"
if [[ "$ID" != "$PROGNAM" ]] ; then
xterm -geom "${GEOM}" -T "$PROGNAM" -e "$0" $@ &
exit 0
fi
fi
# Rest of your function goes here.
This works best when called as a separate script file, however. Otherwise you will have to dance around multiple fork and exit points which can get unpleasant.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.