My assignment wants me to gather all the processes being run by using a ps -ef | grep -v grep | grep <PID#> I need to use, but I am receiving an illegal hardware instruction. here is the code:
//some code^
int PID = getpid();
char command[] = "ps -ef | grep -v grep | grep ";
char PIDString[12];
sprintf(PIDString, "%i", PID);
system("clear");
//These print just fine
//printf("%s\n",command);
//printf("ID %s",PIDString);
strcat(command, PIDString);
system(command);
When I tried to insert a %i. into the string "grep ...%.." it wouldn't work. Is there a way to do this instead of changing the int to a string and concatenating them. Please let me know what I'm missing to grasp.
char command[] = "ps -ef | grep -v grep | grep ";
Your compiler will allocate just enough memory to hold this string.
If you want to have additional space available, you could make sure by specifying the size of the array.
char command[100] = "ps -ef | grep -v grep | grep ";
You may wish to define a constant to hold that value, rather than just a magic number.
Related
I wanted to execute who command and cut out the needed info like who | cut -d " " -f 1,21,23 but by using the system() function in c.
I tried doing system("who | cut -d " " -f 1,21,23") which did not work.
The code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define ErrorBC -69
int main(int argc, char* argv[]){
if(argc < 2){
printf("No arguments passed\n");
return -69;
}
else{
int i=0;
for(i=1;i<argc;i++){
if((strcmp("kernel",argv[i]))==0){
system("uname -s -r");
}
else if(((strcmp("ulog",argv[i]))==0)){
system("who | cut -d " " -f 1,21,23");
}
else{
printf("%s is not a valid options\n",argv[i]);
}
}
}
}
The output:
c99 test.c
/usr/sahil: ./a.out ulog
Usage: cut {-b <list> [-n] | -c <list> | -f <list> [-d <char>] [-s]} file ...
With "who | cut -d " " -f 1,21,23" you have two strings: "who | cut -d " and " -f 1,21,23". They are concatenated to "who | cut -d -f 1,21,23".
To include double-quotes inside C strings you need to escape them with the backslash: "who | cut -d \" \" -f 1,21,23".
The command is : ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R'
I am running it through adb shell. Basically, I want a list of processes (and certain parameters) which are currently in the run queue. This is working fine if I run it directly through the shell.
However, if I put it in a C program and cross-compile it to run on Android, it's not working. Only ps -c -p is working (I have checked that). But on running this ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R', I get the output :
usage: tr [-cds] SET1 [SET2]
Translate, squeeze, or delete characters from stdin, writing to stdout
-c/-C Take complement of SET1
-d Delete input characters coded SET1
-s Squeeze multiple output characters of SET2 into one character
tr: Needs 1 argument
usage: cut OPTION... [FILE]...
Print selected parts of lines from each FILE to standard output.
-b LIST select only these bytes from LIST.
-c LIST select only these characters from LIST.
-f LIST select only these fields.
-d DELIM use DELIM instead of TAB for field delimiter.
-s do not print lines not containing delimiters.
-n don't split multibyte characters (Ignored).
cut: Needs -fcb
I think the output of ps -c -p is not being conveyed to tr, which doesn't convey it to cut.
Can you please suggest what's the issue?
Here's the code I am using:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 128
int main(int argc,char **argv)
{
char *cmd4 = "ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R'";
system(cmd4);
FILE *fp;
char buf[BUFSIZE];
// Another method
if ((fp = popen(cmd4, "r")) == NULL) {
printf("Error opening pipe4!\n");
return -1;
}
while (fgets(buf, BUFSIZE, fp) != NULL) {
// Do whatever you want here...
printf("cmd 4 running!");
printf("OUTPUT: %s", buf);
}
if(pclose(fp)) {
printf("Command not found or exited with error status4\n");
return -1;
}
return 0;
}
In the shell, you're using the following command:
ps -c -p | tr -s " " | cut -d " " -f 2,6-10,13 | grep 'R'
In C, you're passing the following to system (and later to popen):
ps -c -p | tr -s | cut -d -f 2,6-10,13 | grep 'R'
See the difference? Quotes need to be escaped in C source code. Also, when you have trouble like this, be sure to output the relevant data so you can see what is actually happening instead of what you planned. A simple puts(cmd4) would have revealed this instantly.
Im trying to execute the following code in my C program but it seems that the -m1 switch is unable to terminate the pipe. As a result the program keeps reading the entire 16 GB file. Any help would be appreciable.
char *cmd=NULL;
cmd = malloc (200);
if (cmd != NULL) {
strcpy (cmd, "sudo hexdump -v -e '");
strcat(cmd,"\"");
strcat(cmd,"%010_ad |");
strcat(cmd,"\"");
strcat(cmd," 100000/1 ");
strcat(cmd,"\"");
strcat(cmd,"%_p");
strcat(cmd,"\"\"");
strcat(cmd,"|\\n");
strcat(cmd,"\"");
strcat(cmd,"' -s 2437150492 /run/SDdownload.dd | grep -m 1 -E -o ");
strcat(cmd,"\"");
strcat(cmd,"single_install Secure cloud storage and file sharing");
strcat(cmd,"\"");
strcat(cmd,">./files/Sync.com/installation.txt");
printf("Command -> %s\n",cmd);
system(cmd);
Ok so I've googled for an hour or more and I still didn't solved my issue.
I have these 3 bash commands:
find . -name "file_name" -exec du -h {} \; -> gives me the file's size
ls -l --time-style='+%d/%m/%Y' "file_name" | awk '{print $6}' -> last modiffied date
ls -l "file_name"|cut -d" " -f1 -> file's permissions
And I want to execute these 3 commands at a time using system();
Output example :
File size : ...
Last modiffied date : ...
File permissions : ...
My attempt :
char command[256];
char file_name[]={"myfile.txt"};
sprintf(command,"find . -name %s -exec du -h {} \; &&
ls -l --time-style='+%D/%m/%Y' %s | awk '{print $6}' &&
ls -l %s | cut -d' ' -f1",
file_name,file_name,file_name);
system((char*)command);
NOTES : I don't have to worry about the file's path because I'm using files from the same directory I execute my c program.
Compilation error : 'Sh: && is not expected'
You needed to add a percent sign in front of each percent sign you wanted in your command, otherwise it would be interpreted by sprintf as a print-mask introducer. Additionally, you need to add a back-slash in front of each back-slash you want in your command, otherwise it would be interpreted by sprintf as an introducer (e.g. for \n etc.). Additionally, I modified the sprintf second argument (i.e. the string)... I put ending quotes at the end of each physical line in your code, and at the beginning of the next physical line in your code.
Here is an example that may be what you are looking for (at least it compiles and runs):
#include <stdio.h>
int main(int argc, char **argv)
{
char command[256];
char file_name[] = "myfile.txt";
sprintf(command, "find . -name %s -exec du -h {} \\; && "
"ls -l --time-style='+%%D/%%m/%%Y' %s | awk '{print $6}' && "
"ls -l %s | cut -d' ' -f1",
file_name,
file_name,
file_name);
printf("command: -->%s<--\n\n\n", command);
system((char*)command);
}
I use Bash to get a c program variables' addresses. How to know if the address is related to an integer, float or double variable?
As the comments mentioned you can't get the type unless you have debugging symbols. But if you do have the symbols then you can use GDB. Consider this program:
#include <stdio.h>
static int i = 42;
static float f = 42.1;
static double d = 42.2;
int main (int argc, char **argv) {
printf("i=%d, f=%f, d=%f\n", i, f, d);
return (0);
}
If you compile it as follows:
gcc -g -o types types.c
You can then get the type of variables like this:
ubuntu#ubuntu:~$ echo ptype i | gdb --silent types
Reading symbols from /home/ubuntu/types...done.
(gdb) type = int
ubuntu#ubuntu:~$ echo ptype f | gdb --silent types
Reading symbols from /home/ubuntu/types...done.
(gdb) type = float
ubuntu#ubuntu:~$ echo ptype d | gdb --silent types
Reading symbols from /home/ubuntu/types...done.
(gdb) type = double
ubuntu#ubuntu:~$
If you only have the symbol table and not full debugging information, i.e. the binary was compiled with -g, then processed by strip -d, then the best you can do is get the size of the given object using binary dump utilities such as nm, objdump or readelf.
Using nm:
ubuntu#ubuntu:~$ read addr next_addr <<< $(nm -n types | grep -A1 ' i$' | cut -d' ' -f1)
ubuntu#ubuntu:~$ echo "ibase=16; ${next_addr^^} - ${addr^^}" | bc
4
ubuntu#ubuntu:~$ read addr next_addr <<< $(nm -n types | grep -A1 ' f$' | cut -d' ' -f1)
ubuntu#ubuntu:~$ echo "ibase=16; ${next_addr^^} - ${addr^^}" | bc
4
ubuntu#ubuntu:~$ read addr next_addr <<< $(nm -n types | grep -A1 ' d$' | cut -d' ' -f1)
ubuntu#ubuntu:~$ echo "ibase=16; ${next_addr^^} - ${addr^^}" | bc
8
ubuntu#ubuntu:~$
This works as follows:
nm -n lists the symbol table with addresses in numerical order
grep -A1 ' i$ filters the symbol we are interested long with the immediately following line. Note this is a regular expression search constructed to find exactly the symbol i and nothing else
cut -d' ' -f1 lists just the addresses
read addr next_addr puts the addresses into two variables
The expression piped into bc then calculates the difference between the address we are interested in and the immediately following address. Note the addresses are in hex, so we need to tell bc that with the ibase parameter. Also the ${var^^} bash expansion converts the hex digits a-f to uppercase as bc requires this.