Terminal command not recognised? - macos

when I type this directly into the terminal - it works as expected and returns 0 if the app is not running, and 1 if it is.
lsappinfo list | grep -v grep | grep bundleID | grep com.test.myapp | wc -l
However, when I use the code below (swift 3 - macOS), it says it is an unrecognised command?
// DECLARE TASK
let task = Process()
// DEFINE THE PATH
task.launchPath = "/usr/bin/lsappinfo"
// DEFINE THE ARGUMENTS
task.arguments = ["list | grep -v grep | grep bundleID | grep com.test.myapp | wc -l"]
// DECLARE outputPipe
let outputPipe = Pipe()
// RUN THE TASK
task.launch()
// DECLARE data
let data = outputPipe.fileHandleForReading.readDataToEndOfFile()
// DECLARE output AS THE UTF-8 STRING OF THE TERMINAL'S OUTPUT
let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
print(output!)
if output == "0" {
print("App is not running!")
} else {
print("App is running!")
}
// PAUSE UNTIL COMPLETED
task.waitUntilExit()
Can someone please tell me where I have gone wrong, as I am new to Swift, and still struggling to get my head around the language / syntax.
Thank you all in advance.

Piping operations are not arguments to the process, they are instructions to a shell to connect several separate processes. If the task construct in swift expects a process and a set of command-line argument, then one way to do this here would maybe be to launch the bash binary, and then put -c "lsappinfo list | grep -v grep | grep bundleID | grep com.test.myapp | wc -l" as the full set of arguments. That way, you would let bash sort out what's needed to accomplish the piping.

Related

Bash printf value does not show up or is cut off

I trying to get a value from a command into a var
and then print it our using printf.
Problem: i got the value in the var but with printf it does not appear
or is cut off.
INFO: In my script im calling redis-cli info memory
and to check whats wrong i tried a call on vmstat -s.
Working vmstat test:
format="%-16s | %-16s"
container_name="some_name"
used_memory=$(vmstat -s | sed -n "s/^\(.*\) K used memory.*$/\1/p")
row=$(printf "${format}" "${container_name}" "${used_memory}")
echo "${row}"
Output: some_name | 11841548
The actual script that is not working:
format="%-50s | %-16s"
container_name="totally_secret_container_name_1"
used_memory=$(docker exec -it "${container_name}" redis-cli info memory | sed -n "s/^used_memory_human:\(.*\)$/\1/p")
row=$(printf "${format}" "${container_name}" "${used_memory}")
echo "${row}"
Output: ecret_container_name_1 | 1.08M
Weird is than when i set the format to format="%-50s | %-1s"
then it works - the container name (left value) gets printed correctly.
What happen here?
How can i fix this?
Thanks for your time!
You need to remove the \r characters in the output that are causing it to go back to the beginning of the line and overwrite.
used_memory=$(docker exec -it "${container_name}" redis-cli info memory | sed -n "s/^used_memory_human:\(.*\)$/\1/p")
used_memory=${used_memory//$'\r'/}
row=$(printf "${format}" "${container_name}" "${used_memory}")
This uses the bash ${variable//old/new} replacement operator.

Using groovy, how do you pipe multiple shell commands?

Using Groovy and it's java.lang.Process support, how do I pipe multiple shell commands together?
Consider this bash command (and assume your username is foo):
ps aux | grep ' foo' | awk '{print $1}'
This will print out usernames - one line for some processes related to your user account.
Using Groovy, the ProcessGroovyMethods documentation and code says I should be able to do this to achieve the same result:
def p = "ps aux".execute() | "grep ' foo'".execute() | "awk '{print $1}'".execute()
p.waitFor()
println p.text
However, I can't get any text output for anything other than this:
def p = "ps aux".execute()
p.waitFor()
println p.text
As soon as I start piping, the println does not print out any anything.
Thoughts?
This works for me :
def p = 'ps aux'.execute() | 'grep foo'.execute() | ['awk', '{ print $1 }'].execute()
p.waitFor()
println p.text
for an unknown reason, the parameters of awk can't be send with only one string (i don't know why! maybe bash is quoting something differently). If you dump with your command the error stream, you'll see error relative to the compilation of the awk script.
Edit : In fact,
"-string-".execute() delegate to Runtime.getRuntime().exec(-string-)
It's bash job to handle arguments containing spaces with ' or ". Runtime.exec or the OS are not aware of the quotes
Executing "grep ' foo'".execute() execute the command grep, with ' as the first parameters, and foo' as the second one : it's not valid. the same for awk
You can do this to just let the shell sort it out:
// slash string at the end so we don't need to escape ' or $
def p = ['/bin/bash', '-c', /ps aux | grep ' foo' | awk '{print $1}'/].execute()
p.waitFor()
println p.text
This has worked for me
def command = '''
ps aux | grep bash | awk '{print $1}'
'''
def proc = ['bash', '-c', command].execute()
proc.waitFor()
println proc.text
If you want to run multiple commands, you can add it in the command.
def command = '''
ls -ltr
cat secret
'''
def proc = ['bash', '-c', command].execute()
proc.waitFor()
println proc.text
If you want it async I recommend
proc.consumeProcessOutputStream(new LineOrientedOutputStream() {
#Override
protected void processLine(String line) throws IOException {
println line
}
}
);

Assigning shell command output to a variable in ROOT

I am executing a shell command in my ROOT code using gSystem which returns an int, as seen here gSystem->Exec(). But when I try to assign the output to a in code variable the assignment doesn't happen.
int low_edge = 0;
low_edge = gSystem->Exec("ls ./folder | egrep -o '[0-9]{3,3}' | head -1");
I have tried also gSystem->Exec("ls ./folder | egrep -o '[0-9]{3,3}' | head -1") >> low_edge, but it didn't work out.
Am I missing something obvious?
The return value of gSystem->Exec() is 0 or -1 depending on if the command was successful.
What you want is:
TString GetFromPipe(const char* command)
TString the_output=gSystem->GetFromPipe("ls ./folder | egrep -o '[0-9]{3,3}' | head -1");
should work, you just need to convert TString to int.

Unix. Call a variable inside another variable

Currently I have a script like this. The intended purpose of this script is to use the function Getlastreport and retreive the name of lastest report in a folder. The folders name are typical a random generated number every night. I want to call the variable Getlastreport and put it inside Maxcashfunc.
Example :
Getlast report = 3473843.
Use MAXcashfunc grep -r "Max*" /David/reports/$Getlastreport[[the number 3473843 should be here ]]/"Moneyfromyesterday.csv" > Report`
Script:
#!bin/bash
Getlastreport()
{
cd /David/reports/ | ls -l -rt | tail -1 | cut -d' ' -f10-
}
MAXcashfunc()
{
grep -r "Max*" /David/reports/$Getlastreport/"Moneyfromyesterday.csv" > Report
}
##call maxcash func
MAXcashfunc
You can use:
MAXcashfunc() {
grep -r "Max" /David/reports/`Getlastreport`/"Moneyfromyesterday.csv" > Report
}
`Getlastreport` - Call Getlastreport and get its output.
If I follow your question, you could use
function Getlastreport() {
cd /David/reports/ | ls -l -rt | tail -1 | cut -d' ' -f10-
}
function MAXcashfunc() {
grep -r "Max" /David/reports/$(Getlastreport)/"Moneyfromyesterday.csv" > Report
}

Unix user created variables

I am going though some growing pains with Unix. My question:
I want to be able to print all my user defined variables in my shell. Let say I do the following in the shell:
$ x=9
$ y="Help"
$ z=-18
$ R="My 4th variable"
How would I go about printing:
x y z R
You should record your variables first at runtime with set, then compare it later to see which variables were added. Example:
#!/bin/bash
set | grep -E '^[^[:space:]]+=' | cut -f 1 -d = | sort > /tmp/previous.txt
a=1234
b=1234
set | grep -E '^[^[:space:]]+=' | cut -f 1 -d = | sort > /tmp/now.txt
comm -13 /tmp/previous.txt /tmp/now.txt
Output:
a
b
PIPESTATUS
Notice that there are still other variables produced by the shell but is not declared by the user. You can filter them with grep -v. It depends on the shell as well.
Add: Grep and cut could simply be just one sed a well: sed -n 's/^\([^[:space:]]\+\)=.*/\1/p'
Type set:
$ set
Apple_PubSub_Socket_Render=/tmp/launch-jiNTOC/Render
BASH=/bin/bash
BASH_ARGC=()
BASH_ARGV=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="3" [1]="2" [2]="51" [3]="1" [4]="release" [5]="x86_64-apple-darwin13")
BASH_VERSION='3.2.51(1)-release'
COCOS2DROOT=/Users/andy/Source/cocos2d
COLUMNS=80
DIRSTACK=()
...
(Oh, and BTW, you appear to have your variable syntax incorrect as you assign, say, A but print $A)
If variables are exported then you can use env command in Unix.

Categories

Resources