Do you know of any alternatives to wmctrl? A program that lets you manipulate windows and window management from the command line.
One drawback with wmctrl is that whilst you can manipulate the current window, you cannot get wmctrl to list information about the current window (it ignores -r).
To find the id of the currently active window, use:
xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}"
Using this id, you can then get a lot of information about the currently active window:
xprop -id $(xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}")
From there, you can grep what you need, or make it show just the desired field the same way I extracted _NET_ACTIVE_WINDOW above. So, to find the PID of the currently active window, you would append -f _NET_WM_PID 0c " \$0\\n" _NET_WM_PID to the command above, making it:
xprop -id $(xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}") -f _NET_WM_PID 0c " \$0\\n" _NET_WM_PID | awk "{print \$2}"
Note that wmctrl also accepts the same kind of id in combination with the -i flag.
You can trick wmctrl into outputting the ID number of the active window by turning on verbose mode and telling it to move the active window with an invalid parameter:
wmctrl -v -r :ACTIVE: -e dummy
While this does exit with an error status, it also outputs the ID number of the active window:
envir_utf8: 1
Using window: 0x08400004
The -e option expects a list of comma separated integers: "gravity,X,Y,width,height"
Once you have the ID number of the active window, you can list all the windows and search for that ID number:
wmctrl -l
It's awkward to get information about the active window with wmctrl, but it's possible.
xdotool is a reasonable alternative (github project here), although unfortunately the author doesn't seem to care about it much any more.
My experience with wmctrl version 1.07 under RH Linux 5.5 and 5.6 64-bits is that
wmctrl gets completely lost at times. For instance, when looking for a firefox window
the following returns nothing:
% wmctrl -lpGx | grep -i 'Firefox'
My suspicion is that wmcntl cannot find firefox windows due to the nature of the window manager, in this case, metacity. This manager seems to reparent windows and perhaps this causes wmctrl not to list firefox windows. 'xwininfo' does list the firefox windows.
If you have access to xdotool (my version is 2.20110530.1) then you can try:
% mywin=`xwininfo -root -tree | awk '/- Mozilla Firefox/ { printf $1; exit}'`
% xdotool windowactivate --sync $mywin mousemove --window $mywin 0 0
This makes firefox active, makes it the top window in the stack on your desktop, and puts the mouse over it (as is sometimes needed when a user's environment sets focus to a window under the mouse without requiring a click.) If you don't want the mouse to move simply
remove 'mousemove --window $mywin 0 0' from the above.
Note: I had the same problem with finding Konqueror windows on the same Linux systems.
window id
wmctrl -a :ACTIVE: -v 2>&1 | grep "Using window: " | awk "{print \$3}"
You can check xdo which can do a decent job with minimal ressources.
Related
I use
tail -f file | grep pattern
all the time for continuous grep.
However, is there a way I can make grep output its pattern at the same spot, say at the top of the screen? so that the screen doesn't scroll all the time?
My case is something like this: tail -f log_file | grep Status -A 2 will show the current status and what changed it to that status. The problem is the screen scrolls and it becomes annoying. I'd rather have the output stuck on the first 3 lines in the screen.
Thank you!
you could use the watch command; which will always execute the same command, but the position on the screen will stay the same. The process might eat some more CPU or memory though:
watch "tail file | grep pattern"
by default watch executes that command every 2 seconds. You can adjust up to 0.1 seconds using:
watch -n 0.1
NOTE
As noted by #etanReisner: this is not exactly the same as tail -f: tail -f will change immediately if something is added to your logfile, the watch command will only notice that when it executes, ie every 2 (or 0.1 seconds).
Assuming you are using a vt100 compatible emulator...
This command will tail a file, pipe it into grep, read it a line at a time and then display it in reverse on the top line of the screen:
TOSL=$(tput sc;tput cup 0 0;tput rev;tput el)
FROMSL=$(tput sgr0; tput rc)
tail -f file | grep --line-buffered pattern | while read line
do
echo -n "$TOSL${line}$FROMSL"
done
It assumes your output appears a line at a time. If you want more than one line, you can read more than a line, but you have to decide how you want to buffer the output. You could also use the csr terminfo command to set up an entire separate scrolling region instead of just having one line.
Here is the scrolling region version with a ten line status area at the top:
TOSL=$(tput sc; tput csr 0 10; tput cup 10 0;tput rev;tput el)
FROMSL=$(tput sgr0; tput rc;tput csr 10 50;tput rc)
tail -f file | grep --line-buffered pattern | while read line
do
echo -n "$TOSL${line}
$FROMSL"
done
Note that it is not impossible that your display will be corrupted from time-to-time as it could be that the output from your main shell and your background task get mixed up.
Simply replace the newlines with carriage returns.
tail -f file | grep --line-buffered whatever | tr '\012' '\015'
The line buffering is to avoid jumpy output; see http://mywiki.wooledge.org/BashFAQ/009
This is quick and dirty. As noted in comments, this will leave the previous contents of the line underneath, so a shorter line will not completely overlay a longer line. You could add some control codes to address that, but then you might as well use Curses for the formatting too, like in rghome's answer.
How can I find the number of open tabs in my terminal?
I can get the Id of the window by using xwininfo -name and giving a name of one of the tabs. For example:
xwininfo -name "<name of a tab>" on my machine resulted in:
xwininfo: Window id: 0x3000006 "<name of tab>"
...some more info
Is there a way to know the number of tabs currently open? I'm using Ubuntu with tcsh but bash solutions are welcome also because they may hint for the solution with tcsh.
You can try something like this:
ps --ppid $(pgrep gnome-terminal) | grep tcsh | wc -l
top -c
Top lists all the processes, there are good options to filter the processes by username by using the option -u but I am wondering if there is any easy way to filter the processes based on processname listed under COMMAND column of the top output.
For Example I would want like top -some option -substring of processname and top displays pids only having this substring in its command name
Using pgrep to get pid's of matching command lines:
top -c -p $(pgrep -d',' -f string_to_match_in_cmd_line)
top -p expects a comma separated list of pids so we use -d',' in pgrep. The -f flag in pgrep makes it match the command line instead of program name.
It can be done interactively
After running top -c , hit o and write a filter on a column, e.g. to show rows where COMMAND column contains the string foo, write COMMAND=foo
If you just want some basic output this might be enough:
top -bc |grep name_of_process
You can add filters to top while it is running. Just press the o key and then type in a filter expression.
For example, to monitor all processes containing the string "java", use the filter expression COMMAND=java.
You can add multiple filters by pressing o again.
You can filter by user with u. Clear all filters with =.
#perreal's command works great! If you forget, try in two steps...
example: filter top to display only application called yakuake:
$ pgrep yakuake
1755
$ top -p 1755
useful top interactive commands
'c' : toggle full path vs. command name
'k' : kill by PID
'F' : filter by... select with arrows... then press 's' to set the sort
the answer below is good too... I was looking for that today but couldn't find it. Thanks
After looking for so many answers on StackOverflow, I haven't seen an answer to fit my needs.
That is, to make top command to keep refreshing with given keyword, and we don't have to CTRL+C / top again and again when new processes spawn.
Thus I make a new one...
Here goes the no-restart-needed version.
__keyword=name_of_process; (while :; do __arg=$(pgrep -d',' -f $__keyword); if [ -z "$__arg" ]; then top -u 65536 -n 1; else top -c -n 1 -p $__arg; fi; sleep 1; done;)
Modify the __keyword and it should works. (Ubuntu 2.6.38 tested)
2.14.2015 added:
The system workload part is missing with the code above.
For people who cares about the "load average" part:
__keyword=name_of_process; (while :; do __arg=$(pgrep -d',' -f $__keyword); if [ -z "$__arg" ]; then top -u 65536 -n 1; else top -c -n 1 -p $__arg; fi; uptime; sleep 1; done;)
In htop, you can simply search with
/process-name
I ended up using a shell script with the following code:
#!/bin/bash
while [ 1 == 1 ]
do
clear
ps auxf |grep -ve "grep" |grep -E "MSG[^\ ]*" --color=auto
sleep 5
done
Most of the answers fail here, when process list exceeds 20 processes. That is top -p option limit.
For those with older top that does not support filtering with o options, here is a scriptable example to get full screen/console outuput (summary information is missing from this output).
__keyword="YOUR_FILTER" ; ( FILL=""; for i in $( seq 1 $(stty size|cut -f1 -d" ")); do FILL=$'\n'$FILL; done ; while :; do HSIZE=$(( $(stty size|cut -f1 -d" ") - 1 )); (top -bcn1 | grep "$__keyword"; echo "$FILL" )|head -n$HSIZE; sleep 1;done )
Some explanations
__keyword = your grep filter keyword
HSIZE=console height
FILL=new lines to fill the screen if list is shorter than console height
top -bcn1 = batch, full commandline, repeat once
For anyone on a Mac, where top doesn't support the kind of filtering shown in other answers (and the pgrep args are slightly different)... This function will launch top for the processes matching the pattern in the first arg (according to pgrep), and with any other args passed to top.
function topnamed() {
name=$1
shift
top -pid $(pgrep -d ' -pid ' -fi "$name") $#
}
(The "i" in "-fi" makes it case-insensitive.)
Basic example showing any "python" processes:
topnamed python
Example with additional args for top:
topnamed python -o mem
It has the downside (mentioned in other answers) of only including the processes at launch time.
what about this?
top -c -p <PID>
This expect script will filter processes by name and show newly created ones. It is basically automate the user interaction with top by sending 'o' and 'COMMMAND=my_program' for you. similar to #nos Answer.
file: topname.exp
#!/usr/bin/expect --
if {[llength $argv] < 1 } {
send_user "Usage: topname process_name top_cmd_args \n"
exit 1
}
set keyword [lindex $argv 0]
spawn top {*}[lrange $argv 1 end]
expect {
-re .
{
send "o\r"
expect "*add filter*"
send "COMMAND=${keyword}\r"
interact
}
}
So you would use it like:
./topname.exp my_program
./topname.exp java # this filters java processes
Also it passed other flags that top accepts like -u
e.g.
./topname.exp java -u root # this filters java processes by root user
./topname.exp java -u root -d 1 # this filters java processes by root user and delay top update by 1 second
I am working on a Java EE application where its logs will be generated inside a Linux server .
I have used the command tail -f -n -10000 MyLog
It displayed last 1000 lines from that log file .
Now I pressed Ctrl + c in Putty to disconnect the logs updation ( as i am feared it may be updated with new requests and I will loose my data )
In the displayed result, how can I search for a particular keyword ?? (Used / String name to search but it's not working)
Pipe your output to PAGER.
tail -f -n LINE_CNT LOG_FILE | less
then you can use
/SEARCH_STRING
Two ways:
tail -n 10000 MyLog| grep -i "search phrase"
tail -f -n 10000 MyLog | less
The 2nd method will allow you to search with /. It will only search down but you can press g to go back to the top.
Edit: On testing it seems method 2 doesn't work all that well... if you hit the end of the file it will freeze till you ctrl+c the tail command.
You need to redirect the output from tail into a search utility (e.g. grep). You could do this in two steps: save the output to a file, then search in the file; or in one go: pipe the ouput to the search utility
To see what goes into the file (so you can hit Ctlr+c) you can use the tee command, which duplicates the output to the screen and to a file:
tail -f -n -10000 MyLog | tee <filename>
Then search within the file.
If you want to pipe the result into the search utility, you can use the same trick as above, but use your search program instead of tee
Controlling terminal output on the fly
While running any command in a terminal such as Putty you can use CTRL-S and CTRL-Q to stop and start output to the Putty terminal.
Excluding lines using grep
If you want to exclude lines that contain a specific pattern use grep -v the following would remove all line that contain the string INFO
tail -f logfile | grep -v INFO
Show lines that do not contain the words INFO or DEBUG
tail -f logfile | grep -v -E 'INFO|DEBUG'
Finally, the MOTHER AND FATHER of all tailing tools is xtail.pl
If you have perl on your host xtail.pl is a very nice tool to learn and in a nutshell you can use it to tail multiple files. Very handy.
You can just open it with less command
less logfile_name
when you open the file you can use this guide here
Tip: I suggest, first to use G to go to the end of the file and then to you use Backward Search
I want to tail multiple files (and follow them) in CentOS, I've tried this:
tail -f file1 file2 file3
but the output is very unfriendly
I've also had a look at multitail but can't find a CentOS version.
What other choices do I have?
Multitail is available for CentOS in rpmforge repos. To add rpmforge repository check the documentation on 3rd Party Repositories.
I found the solution described here work well on centos:
The link is http://www.thegeekstuff.com/2009/09/multitail-to-view-tail-f-output-of-multiple-log-files-in-one-terminal/
Thanks to Ramesh Natarajan
$ vi multi-tail.sh
#!/bin/sh
# When this exits, exit all back ground process also.
trap 'kill $(jobs -p)' EXIT
# iterate through the each given file names,
for file in "$#"
do
# show tails of each in background.
tail -f $file &
done
# wait .. until CTRL+C
wait
You could simulate multitail by opening multiple instances of tail -f in Emacs subwindows.
I usually just open another xterm and run a separate 'tail -f' there.
Otherwise if I'm using the 'screen' tool, I'll set up separate 'tail -f' commands there. I don't like that as much because it takes a few keystrokes to enable scrolling in screen before using the Page Up and Page Down keys. I prefer to just use xterm's scroll bar.
You can use the watch command, i use it to tail two files at the same time:
watch -n0 tail -n30 file1 file2
A better answer to an old question...
I create a shell function in my .bashrc (obviously assumes you're using bash as your shell) and use tmux. You can probably complicate this a whole lot and do it without the tempfile, but the quoting is just ugly if you're trying to ensure that files with spaces or other weird characters in the name still work.
multitail ()
{
cmdfile=`mktemp`
echo "new-session -d \"tail -f '$1'\"" >$cmdfile
shift
for file in "$#"
do
echo "split-window -d \"tail -f '$file'\"" >>$cmdfile
done
echo "select-layout even-vertical" >>$cmdfile
tmux source-file $cmdfile \; attach && rm -f $cmdfile
}