I wrote a test.c:
#include <unistd.h>
#include <stdio.h>
int main()
{
while(1)
{
sleep(1);
printf("====test====\r\n");
}
return 0;
}
then i compile it : gcc ./test.c -o ./test
and the i wrote a shell script:
#!/bin/sh
./test &
and then i made this script to be executed automatically on system boot.
then I login to the Linux system using secureCRT in SSH protocol.
using "ps aux | grep test" i can see the test process running,
but i just cannot see the test's output, some people told me because the test
output to tty, and i am using pts.
could anybody tell me the specific reason and how can i get the output?
thanks in advance!
It doesn't output anything because it got no terminal attached.
If you want your output to be visible to every terminal connected to the system, use wall
./test | wall
(it will be very annoying)
I suggest you to redirect the output to a log file.
Related
On Linux, every process has its own root directory. For most processes, this is /. However, chroot can change that. This information is exposed via /proc. However, how do I find out the root directory of a process programmatically? Is there a syscall, or, libc function for it?
I don't know whether there is another way, but lots of programs rely on the machine readable files in /proc to get additional information about processes and there's nothing inherently wrong with that.
Here's an example of a process finding its own root dir programmatically via /proc:
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
int main() {
char foo[PATH_MAX+1];
int count = readlink("/proc/self/root", foo, PATH_MAX);
if(count < 0) {
perror("Can't find root dir (is /proc mounted here?)");
} else {
foo[count]=0;
printf("My root dir is %s\n", foo);
}
}
Well there isn't. There exists a command to do this which is pwdx, here is its code https://elixir.bootlin.com/busybox/latest/source/procps/pwdx.c. It also reads root dir from /proc. You can get the pid of your process using getpid function.
One simple way is to just use a for loop. This is a one-liner that will print out the root directory of each of the processes you wish (proc1, proc2, proc3):
for i in $(ps -ef | grep -E 'proc1|proc2|proc3' | awk '{ print $2 }'); do ls -ld /proc/$i/root; done
I am trying to enable printing the debug messages on the console.
#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int test_hello_init(void)
{
printk(KERN_INFO"%s: In init\n", __func__);
return 0;
}
static void test_hello_exit(void)
{
printk(KERN_INFO"%s: In exit\n", __func__);
}
module_init(test_hello_init);
module_exit(test_hello_exit);
To get the Info messages on the console, i executed the following command: dmesg -n7
cat /proc/sys/kernel/printk
7 4 1 7
When I load the module using insmod, i don't get any message on the terminal, while it is available when I type dmesg. What mistake i am making here.
Messages from kernel are not printed on terminal (unless it's specified as console= in kernel cmdline). They are appended to kernel log, which exists in kernel. It's accessible to user space programs via device file /dev/kmsg. This file is read by dmesg command in order to print kernel log content on terminal.
I'm trying to run the following program inside a Docker container, which is started with --privileged:
root#1df00aaf673d:~# cat > sysconf_test.c
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
int main() {
long n = sysconf(_SC_CHILD_MAX);
printf("%ld %d\n", n, errno);
return 0;
}
root#1df00aaf673d:~# gcc sysconf_test.c ; ./a.out
-1 0
Going by the sysconf man page, "If name corresponds to a maximum or minimum limit, and that limit is indeterminate, -1 is returned and errno is not changed." Is there a way to make it determinate, perhaps by passing an option to the docker run command?
I'll answer my own question: it appears that sysconf returns -1L for "unlimited", although the man page doesn't spell it out:
[root#llg00amn ~]# ulimit -u
120996
[root#llg00amn ~]# docker run -ti debian /bin/bash
root#5668a7acb957:/# ulimit -u
unlimited
After setting the ulimit to an actual number, the program runs fine and returns the right result.
I've executed the following C code in Linux CentOS to create a process.
#include <stdio.h>
#include <unistd.h>
int main ()
{
int i = 0;
while ( 1 )
{
printf ( "\nhello %d\n", i ++ );
sleep ( 2 );
}
}
I've compiled it to hello_count. When I do ./hello_count in a terminal window, The output is like this:
hello 0
hello 1
hello 2
...
When I enter the command in another terminal window
ps -e
the process 2956 ./hello_count is listed there. In the same window, I've stopped the process using:
kill -s SIGSTOP 2956
When I enter the following command again,
ps -e
the process 2956 ./hello_count is still listed.
Then I've entered the following command to resume the process in the same window itself.
kill -s SIGCONT 2956
However, the process resumed in the previous window in which it was executing and giving output.
Is there any command or any method to resume (not to restart) the process with pid 2956 in a different terminal window?
I mean, I need the output like,
hello 8
hello 9
...
in a window other than the one in which I was getting the above output before I've stopped the process.
The problem you're having is that your process is attached to a particular tty and switching tty once a process is started isn't normally possible. See this question.
There are some hacky methods you could consider mind you.
For real world command line scenarios, using screen would allow you to start a command in a virtual terminal and then connect to that terminal from any other. But this isn't a programatic solution which your question seems to indicate you're looking for.
If I use a password as a command-line parameter it's public on the system using ps.
But if I'm in a bash shell script and I do something like:
...
{ somecommand -p mypassword }
...
is this still going to show up in the process list? Or is this safe?
How about sub-processes: (...)? Unsafe right?
coprocess?
Command lines will always be visible (if only through /proc).
So the only real solution is: don't. You might supply it on stdin, or a dedicated fd:
./my_secured_process some parameters 3<<< "b#dP2ssword"
with a script like (simplicity first)
#!/bin/bash
cat 0<&3
(this sample would just dump a bad password to stdout)
Now all you need to be concerned with is:
MITM (spoofed scripts that eaves drop the password, e.g. by subverting PATH)
bash history retaining your password in the commandline (look at HISTIGNORE for bash, e.g.)
the security of the script that contains the password redirection
security of the tty's used; keyloggers; ... as you can see, we have now descended into 'general security principles'
How about using a file descriptor approach:
env -i bash --norc # clean up environment
set +o history
read -s -p "Enter your password: " passwd
exec 3<<<"$passwd"
mycommand <&3 # cat /dev/stdin in mycommand
See:
Hiding secret from command line parameter on Unix
The called program can change its command line by simply overwriting argv like this:
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv) {
int arglen = argv[argc-1]+strlen(argv[argc-1])+1 - argv[0];
memset(argv[0], arglen, 0);
strncpy(argv[0], "secret-program", arglen-1);
sleep(100);
}
Testing:
$ ./a.out mySuperPassword &
$ ps -f
UID PID PPID C STIME TTY TIME CMD
me 20398 18872 0 11:26 pts/3 00:00:00 bash
me 20633 20398 0 11:34 pts/3 00:00:00 secret-program
me 20645 20398 0 11:34 pts/3 00:00:00 ps -f
$
UPD: I know, it is not completely secure and may cause race conditions, but many programs that accept password from command line do this trick.
The only way to escape from being shown in the the process list is if you reimplement the entire functionality of the program you want to call in pure Bash functions. Function calls are not seperate processes. Usually this is not feasible, though.