Ruby - System Command - ps aux - ruby

So I'm trying to find the PID of any process which has the word "control" in it. I'm in ruby on linux. This is the basic code so far
`ps aux | grep control`
If I run that in ruby, all the distinct lines that would come back when run in linux, get concatenated into one long string. How can I have ruby read the results in as a list, instead of one long string?

You can split it on the newline characters like so:
lines = (`ps aux | grep control`).split(/\n/)
With that done you can iterate over them, select things out using a regex, etc..

Since you are on linux, you could could examine the /proc filesystem. There are /proc// directories, and /proc//cmdline has the command line.

Related

Why does a pipe to a command group only work for some commands?

I was interested in keeping the header of the input in the grep output just like in the question Include header in the 'grep' result.
Although a working solution (using sed) is presented right in the question, the answer with most upvotes attracted my attention. It allows utilizing grep --color, for example. It suggests piping the input to a command group with the commands head and grep, e.g.:
ps -ef | { head -1; grep python; }
However, as written in the linked answer and a comment, this does not work with all commands on the left side of the pipe. It works well with ps or lsof but does not work for df, ls and others. When using them, only the output of the first command in the group is printed:
$ df | { head -1; grep '/'; }
Filesystem 1K-blocks Used Available Use% Mounted on
$
Could anyone explain why piping to a command group only works for some commands? Is there any way to make it work universally?
The answer to your question is in comments of the linked answer.
Apparently ps -e is sending the header line first, then not sending anything, then buffering the rest of the output. head must think the stream is closed after the first line, so it exits, leaving grep to see the rest.
It only works by accident.
Is there any way to make it work universally?
Everything is possible, but, you may need to recode and recompile everything else. So... not possible, sorry.

How to isolate logical volume group UDID for shell script?

I am currently looking to use "diskutil cs list" to show the logical volume groups. I need to be able to isolate the UDID.
Example line from "diskutil cs list"
+-- Logical Volume Group B848BCC7-6FFA-4643-AFE1-56FCA333A6B5
Previously my though process was to;
diskutil cs list | grep 'Group'
I think AWK will be a better route to show just the string of letters and numbers. I have been unsuccessful in finding out how to dow so
Ultimately, i will use the UDID in a shell script for reformatting a Fusion drive. Using something similar to below.
set a to (do shell script "diskutil cs list|grep 'Group'")
I'd like it to set a to the UDID and not the full line.
Try:
diskutil cs list | awk '/Group/{print $NF}'
/Group/ will look for lines that have the word Group in them. It is just a filter mechanism. If all your output lines have Group in them, then you can remove /Group/ part.
Once it finds those lines, it will print the last element of that line. awk by default splits the line on space.
Depending how new your system is you might have lsblk(1) command, that is made to be combined with scripts. The utility can limit what block devices are listed, and what information is displayed in format that can be defined.
diskutil cs list | grep -Po 'Group \K\S*$'

What does & do at the end of a wc command?

I am learning the bash environment and cannot understand what I get when running this command:
wc filename.txt &
It returns an array with a 1-digital integer and another integer, neither of them matches any other result I can get from wc commands (-l, -m, -w, -c).
Besides the second integer is much bigger than for example the bytes counts. So I terribly wonder.
I browsed forums and found some explanations on the multiple uses of the ampersand in a Unix/Linux environment, but there was nothing that I could relate.
I don't need it, but I won't flush this mystery away, I wish to understand!
Thanks
I imagine the integers you see are similar to this:
[1] 1830
& launches a command in the background, and the shell prints its job number (1) and process id (1830). On a longer-running job, you can use those two numbers to control its execution. See the JOB CONTROL section of the bash man page for more details.
An ampersand at the end of a WC command tells the shell to start executing the command in the background and to get ready for further command line commands.

How does find and printf work when using pipes in bash scripting

Suppose I use the printf in the find command like this:
find ./folder -printf "%f\n" | other command which uses the result of printf
in the other command part, I may be having a sort or something similar
what exactly does printf do in this case? where does it print the file names before the process in the part after "|" happens?
if I sort the filenames for example, it will first sort them, and then print them sorted on the monitor, but before that, how exactly does the part after | get the files unsorted in order to sort them? does the printf in this case give the filenames as input to the part after | and then the part after | prints the file names sorted in the output?
sorry for my english :(
Your shell calls pipe() which creates two file descriptors. Writing into one buffers data in the kernel which is available to be read by the other. Then it calls fork() to make a new process for the find command. After the fork() it closes stdout (always fd 1) and uses dup2() to copy one end of the pipe to stdout. Then it uses exec() to run find (replacing the copy of the shell in the subprocess with find). When find runs it just prints to stdout as normal, but it has inherited it from the shell which made it the pipe. Meanwhile the shell is doing the same thing for other command... with stdin so that it is created with fd 0 connected to the other end of the pipe.
Yes, that is how pipes work. The output from the first process is the input to the second. In terms of implementation, the shell creates a socket which receives input from the first process from its standard output, and writes output to the second process on its standard input.
... You should perhaps read an introduction to Unix shell programming if you have this type of questions.

emacs can invoke shell and execute commands-- can they act on Emacs buffers?

I use Alt-! (Alt-Bang) a lot in Emacs. One of the big things I use it for is
Alt-! cat $logfile | grep 'this' # show me one kind of event
or sometimes
Alt-! cat $logfile | grep 'this' | wc -l # count that one event's occurrences
Two things:
1) No tab-completion from this prompt: why not?
2) What if instead of $logfile, I want to scan one of the Emacs buffers?
To scan an Emacs buffer, use M-| instead of M-!: it passes the region as input to the command. Use M-1 M-| if you want the output of the command to replace the region.
For the particular command you mention, use M-x grep if you want to see all matches. Or you can open it and see the matches with M-x occur.
Alt-| does is shell-command-on-region
with a(ny) numeric prefix (e.g. C-u 1 Alt-|) the region is replaced by the result, otherwise that appears in new buffer

Resources