Execute custom command in awesomewm tooltip - awesome-wm

I have a simple widget to display free memory:
myFreeMemory = awful.widget.watch('bash -c "free -h | awk \'/^Mem:/ {print $3}\'"', 1)
This line produces a single number.
I would like to create a tooltip for it that runs a custom command:
local free_memory_tooltip = awful.tooltip
{
objects = { myFreeMemory },
timer_function = function()
return "free -h"
end,
font = "monaco 18",
timeout=0,
opacity=0.9,
bg="#000000",
fg="#ffffff",
align="top_left"
}
Instead of return "free -h", what should I put to execute this command and return the textual output?

Simplest solution might be to use return io.popen("free -h"):read("*a"), but this uses io.popen which one best avoids in AwesomeWM.
Best solution might be to write a parser for /proc/meminfo yourself. Yuck.
Intermediate solution would be something like the following:
local last_result = ""
local function my_timer_function()
local cmd = "free -h | awk '/^Mem:/ {print $3}'""
awful.spawn.easy_async_with_shell(cmd, function(result)
last_result = result
free_memory_tooltip:set_markup(last_result)
end)
return last_result
end
-- Call it once to initialise its state; otherwise you would get a brief flicker of empty text
my_timer_function()

Related

Need of awk command explaination

I want to know how the below command is working.
awk '/Conditional jump or move depends on uninitialised value/ {block=1} block {str=str sep $0; sep=RS} /^==.*== $/ {block=0; if (str!~/oracle/ && str!~/OCI/ && str!~/tuxedo1222/ && str!~/vprintf/ && str!~/vfprintf/ && str!~/vtrace/) { if (str!~/^$/){print str}} str=sep=""}' file_name.txt >> CondJump_val.txt
I'd also like to know how to check the texts Oracle, OCI, and so on from the second line only. 
The first step is to write it so it's easier to read
awk '
/Conditional jump or move depends on uninitialised value/ {block=1}
block {
str=str sep $0
sep=RS
}
/^==.*== $/ {
block=0
if (str!~/oracle/ && str!~/OCI/ && str!~/tuxedo1222/ && str!~/vprintf/ && str!~/vfprintf/ && str!~/vtrace/) {
if (str!~/^$/) {
print str
}
}
str=sep=""
}
' file_name.txt >> CondJump_val.txt
It accumulates the lines starting with "Conditional jump ..." ending with "==...== " into a variable str.
If the accumulated string does not match several patterns, the string is printed.
I'd also like to know how to check the texts Oracle, OCI, and so on from the second line only.
What does that mean? I assume you don't want to see the "Conditional jump..." line in the output. If that's the case then use the next command to jump to the next line of input.
/Conditional jump or move depends on uninitialised value/ {
block=1
next
}
perhaps consolidate those regex into a single chain ?
if (str !~ "oracle|OCI|tuxedo1222|v[f]?printf|vtrace") {
print str
}
There are two idiomatic awkisms to understand.
The first can be simplified to this:
$ seq 100 | awk '/^22$/{flag=1}
/^31$/{flag=0}
flag'
22
23
...
30
Why does this work? In awk, flag can be tested even if not yet defined which is what the stand alone flag is doing - the input is only printed if flag is true and flag=1 is only executed when after the regex /^22$/. The condition of flag being true ends with the regex /^31$/ in this simple example.
This is an idiom in awk to executed code between two regex matches on different lines.
In your case, the two regex's are:
/Conditional jump or move depends on uninitialised value/ # start
# in-between, block is true and collect the input into str separated by RS
/^==.*== $/ # end
The other 'awkism' is this:
block {str=str sep $0; sep=RS}
When block is true, collect $0 into str and first time though, RS should not be added in-between the last time. The result is:
str="first lineRSsecond lineRSthird lineRS..."
both depend on awk being able to use a undefined variable without error

python 2.7.5: run a whole function in background

I am a beginner with python. I want to run a whole function in the background (because it can take a while or even fail).
Here is the function:
def backup(str):
command = barman_bin + " backup " + str
log_maif.info("Lancement d'un backup full:")
log_maif.info(command)
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = p.communicate()
if p.returncode == 0:
for line in output[0].decode(encoding='utf-8').split('\n'):
log_maif.info(line)
else:
for line in output[0].decode(encoding='utf-8').split('\n'):
log_maif.error(line)
log_maif.info("Fin du backup full")
return output
I want to run this function in the background into a loop :
for host in list_hosts_sans_doublon:
backup(host) # <-- how to run the whole function in background ?
In ksh, I would have written something like backup $host & with backup a function that takes $host as an argument.
What you are looking for is to run the function in a different thread from what I understand. For this you need to use python thread module.
This is how you start a thread:
import threading
def backup(mystring):
print(mystring)
host="hello"
x = threading.Thread(target=backup, [host])
x.start()
Do what ever you want after this and the thread will run separately.

Adding previous lines to current line unless pattern is found in unix shell script

I am facing an issue while adding previous lines to current line for a pattern. I have a 43 MB file in unix. The snippet is shown below:
AAA7034 new value and a old value
A
78698 new line and old value
BCA0987 old value and new value
new value
What I want is :
AAA7034 new value and a old value A 78698 new line and old value
BCA0987 old value and new value new value
Means I have add all the the lines till next pattern is found ( first pattern is : AAA and next pattern is : BCA )
because of high size of files..not sure if awk/sed shall work. Any bash script is appreciated.
You can combine all patterns and perform a regex match. Try something like this (it is just a scratch, you should trim the output if you need):
#!/bin/bash
patterns="^(AAA|BCS|BABA|BCA)"
file="$1"
while IFS= read -r line; do
if [[ "$line" =~ $patterns ]] ; then
echo # prints new line
fi
echo -n $line " " # prints the line itself and a space as a separator
done < "$file"
You can redirect the output to a file, of course.
It's not really clear precisely what you want. You've stated that you want to match the patterns 'AAA' and 'BCA', and later expanded that to "patter shall be like: AAA, BCS, BABA, BCA". I don't know if that means that you only want to match 'AAA', 'BCA', 'AAA, 'BCS, 'BABA', and 'BCA, or if you want to match 3 or 4 characters strings containing only 'A', B', 'C', and 'S', but it sounds like you are just looking for:
awk '/[A-Z]{3,4}/{printf "\n"} { printf "%s ", $0} END {printf "\n"}' input-file
Change the pattern as needed when your requirements are made more precise.
Based on the comment, it is trivial to convert any awk program to perl. Here is (basically) the output of a2p on the above awk script, with changes to reflect the stated pattern:
#!/usr/bin/env perl
while (<>) {
chomp;
if (/AAA|BCA|BCS|BABA/) {
printf "\n";
}
printf '%s ', $_;
}
printf "\n";
You can simplify that a bit:
perl -pe 'chomp; printf "\n" if /AAA|BCA|BCS|BABA/; printf "%s ", $_' input-file; echo

Why does awk function only return last line from file?

I am using awk to reformat some fields in a file and an awk function to fix one field value if it is negative. Here is my awk command:
awk 'function fix_neg(value) {\
if(value < 0)\
return '$new_value'\
else\
return value\
} END { print $2,$1,fix_neg($3) }' input_file.txt
where $new_value was set before this call. I do not understand why this only returns the reformatted last line of input_file.txt (which contains multiple lines of data).
Thanks for your help.
Try this:
awk -v newV="$new_value" '{print $2,$1,($3<0?newV:$3)}' inputfile
In your program, you only got the last line data because you put your print statement in the END{..} block. It is triggered after the whole file was processed, not for each line. Drop the END and it would work as you intended.

Delete a line with a pattern

Hi I want to delete a line from a file which matches particular pattern
the code I am using is
BEGIN {
FS = "!";
stopDate = "date +%Y%m%d%H%M%S";
deletedLineCtr = 0; #diagnostics counter, unused at this time
}
{
if( $7 < stopDate )
{
deletedLineCtr++;
}
else
print $0
}
The code says that the file has lines "!" separated and 7th field is a date yyyymmddhhmmss format. The script deletes a line whose date is less than the system date. But this doesn't work. Can any one tell me the reason?
Is the awk(1) assignment due Tuesday? Really, awk?? :-)
Ok, I wasn't sure exactly what you were after so I made some guesses. This awk program gets the current time of day and then removes every line in the file less than that. I left one debug print in.
BEGIN {
FS = "!"
stopDate = strftime("%Y%m%d%H%M%S")
print "now: ", stopDate
}
{ if ($7 >= stopDate) print $0 }
$ cat t2.data
!!!!!!20080914233848
!!!!!!20090914233848
!!!!!!20100914233848
$ awk -f t2.awk < t2.data
now: 20090914234342
!!!!!!20100914233848
$
call date first to pass the formatted date as a parameter:
awk -F'!' -v stopdate=$( date +%Y%m%d%H%M%S ) '
$7 < stopdate { deletedLineCtr++; next }
{print}
END {do something with deletedLineCrt...}
'
You would probably need to run the date command - maybe with backticks - to get the date into stopDate. If you printed stopDate with the code as written, it would contain "date +...", not a string of digits. That is the root cause of your problem.
Unfortunately...
I cannot find any evidence that backticks work in any version of awk (old awk, new awk, GNU awk). So, you either need to migrate the code to Perl (Perl was originally designed as an 'awk-killer' - and still includes a2p to convert awk scripts to Perl), or you need to reconsider how the date is set.
Seeing #DigitalRoss's answer, the strftime() function in gawk provides you with the formatting you want (check 'info gawk' as I did).
With that fixed, you should be getting the right lines deleted.

Resources