Write program output to log file containing PID in its name
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
How can I start a program and write its output to a log file, where the log file contains the PID in its name? I tried
program_a > log_$!
which doesn't work since $! is the PID of the last program and `program_a' has not finished when the log file is created.
bash shell pidfile
add a comment |
How can I start a program and write its output to a log file, where the log file contains the PID in its name? I tried
program_a > log_$!
which doesn't work since $! is the PID of the last program and `program_a' has not finished when the log file is created.
bash shell pidfile
Is the program a shell script?
– devnull
Mar 19 '14 at 9:23
@devnull Nope its not
– greole
Mar 19 '14 at 9:26
add a comment |
How can I start a program and write its output to a log file, where the log file contains the PID in its name? I tried
program_a > log_$!
which doesn't work since $! is the PID of the last program and `program_a' has not finished when the log file is created.
bash shell pidfile
How can I start a program and write its output to a log file, where the log file contains the PID in its name? I tried
program_a > log_$!
which doesn't work since $! is the PID of the last program and `program_a' has not finished when the log file is created.
bash shell pidfile
bash shell pidfile
edited Jun 22 '14 at 23:30
Gilles
546k12911101624
546k12911101624
asked Mar 19 '14 at 9:19
greolegreole
159210
159210
Is the program a shell script?
– devnull
Mar 19 '14 at 9:23
@devnull Nope its not
– greole
Mar 19 '14 at 9:26
add a comment |
Is the program a shell script?
– devnull
Mar 19 '14 at 9:23
@devnull Nope its not
– greole
Mar 19 '14 at 9:26
Is the program a shell script?
– devnull
Mar 19 '14 at 9:23
Is the program a shell script?
– devnull
Mar 19 '14 at 9:23
@devnull Nope its not
– greole
Mar 19 '14 at 9:26
@devnull Nope its not
– greole
Mar 19 '14 at 9:26
add a comment |
4 Answers
4
active
oldest
votes
If you are talking about a script I think this is what you are after...
#!/bin/bash
exec 1>test_$$.txt
echo "Hello $$ == $$"
ps
which gave this output
$ cat test_20000.txt
Hello $$ == 20000
PID TTY TIME CMD
18651 ttys000 0:00.06 -bash
20000 ttys000 0:00.00 /bin/bash ./execredir.sh
add a comment |
You can't do that from the shell that way because the commandline is created before the program is even called. You have essentially two options:
1) Create the filename and write to it from within the program (easy if it is a shell script)
2) Create a named pipe, background the process and then redirect the pipe to a file. Like
mkfifo "tmp.log"
program_a > "tmp.log" &
cat "tmp.log" > "log_$!"
Yes, you can.
– Gilles
Mar 19 '14 at 22:33
add a comment |
This doesn't answer the question directly, but I would question why I need to have a file with the pid
in the name. If it is simply a unique filename that you are looking for, then there are more robust ways to do this. Most Unices have a mktemp
command (unfortunately this is not POSIX though). Using GNU mktemp
, you could do:
tmp_file=$(mktemp --tmpdir=. log_XXXXXXXXXX)
program_a >"$tmp_file"
If you have to access the files at a later date, then it may be useful to include the date/time in the filename:
log_file=$(mktemp --tmpdir=. log_"$(date +%F_%T)".XXX)
program_a >"$log_file"
If you are looking to ensure that only one instance of a specific process is running, then on Linux you can use flock
:
(
flock -n 9 || { echo "program_a already running"; exit 1; }
program_a
) 9>/var/lock/program_a
Otherwise, if you are looking to have another program read the output of program_a
while it is still running, then using a file is surely a method of last resort. Much better to use a pipe or a named pipe as per orion's answer.
add a comment |
You can't know the PID until the process has started. So you need to first start the process, then create the log file, then execute the program you want to execute (exec
replaces the calling shell with the given program, it doesn't fork a new process).
sh -c 'exec program_a >log_$$'
$!
is the PID of the last program started in the background and cannot help you here.
Alternatively, you could create the log file under a temporary name, start the program, and then rename the log file, but it's needlessly more complicated.
Is that possible in combination withnohup
? When I put thenohup
command either betweenexec
andprogram_a
or beforesh
, the value of$$
equals to (PID
of theprogram_a instance
) - 1
– stofl
Feb 27 '17 at 22:24
@stofl Sure, you can runnohup sh …
. And indeed$$
is the PID of the new program instance, that was the point of the question. What's the problem?
– Gilles
Feb 27 '17 at 22:33
When I runsh -c 'nohup ./test >log_$$' &
it returns me (right now)9096
. When I callps ax | grep test
, the started process has the PID9097
. I think,nohup
itself is a program that starts a new process detached from the shell and has a different PID because of that. And I think, this difference if1
is not really reliable.
– stofl
Mar 5 '17 at 23:12
1
@stofl You needexec
, otherwisenohup
is a child of the shell and so has a different PID. (Some shells optimize this but not all.)sh -c 'exec nohup ./test >log_$$'
– Gilles
Mar 6 '17 at 0:33
Uh! Yes, that works, thank you. Seems that I have forgotten to write thatexec
in both of my tests!
– stofl
Mar 6 '17 at 18:16
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f120347%2fwrite-program-output-to-log-file-containing-pid-in-its-name%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you are talking about a script I think this is what you are after...
#!/bin/bash
exec 1>test_$$.txt
echo "Hello $$ == $$"
ps
which gave this output
$ cat test_20000.txt
Hello $$ == 20000
PID TTY TIME CMD
18651 ttys000 0:00.06 -bash
20000 ttys000 0:00.00 /bin/bash ./execredir.sh
add a comment |
If you are talking about a script I think this is what you are after...
#!/bin/bash
exec 1>test_$$.txt
echo "Hello $$ == $$"
ps
which gave this output
$ cat test_20000.txt
Hello $$ == 20000
PID TTY TIME CMD
18651 ttys000 0:00.06 -bash
20000 ttys000 0:00.00 /bin/bash ./execredir.sh
add a comment |
If you are talking about a script I think this is what you are after...
#!/bin/bash
exec 1>test_$$.txt
echo "Hello $$ == $$"
ps
which gave this output
$ cat test_20000.txt
Hello $$ == 20000
PID TTY TIME CMD
18651 ttys000 0:00.06 -bash
20000 ttys000 0:00.00 /bin/bash ./execredir.sh
If you are talking about a script I think this is what you are after...
#!/bin/bash
exec 1>test_$$.txt
echo "Hello $$ == $$"
ps
which gave this output
$ cat test_20000.txt
Hello $$ == 20000
PID TTY TIME CMD
18651 ttys000 0:00.06 -bash
20000 ttys000 0:00.00 /bin/bash ./execredir.sh
edited 4 hours ago
Rui F Ribeiro
41.9k1483142
41.9k1483142
answered Mar 19 '14 at 9:51
VicVic
1766
1766
add a comment |
add a comment |
You can't do that from the shell that way because the commandline is created before the program is even called. You have essentially two options:
1) Create the filename and write to it from within the program (easy if it is a shell script)
2) Create a named pipe, background the process and then redirect the pipe to a file. Like
mkfifo "tmp.log"
program_a > "tmp.log" &
cat "tmp.log" > "log_$!"
Yes, you can.
– Gilles
Mar 19 '14 at 22:33
add a comment |
You can't do that from the shell that way because the commandline is created before the program is even called. You have essentially two options:
1) Create the filename and write to it from within the program (easy if it is a shell script)
2) Create a named pipe, background the process and then redirect the pipe to a file. Like
mkfifo "tmp.log"
program_a > "tmp.log" &
cat "tmp.log" > "log_$!"
Yes, you can.
– Gilles
Mar 19 '14 at 22:33
add a comment |
You can't do that from the shell that way because the commandline is created before the program is even called. You have essentially two options:
1) Create the filename and write to it from within the program (easy if it is a shell script)
2) Create a named pipe, background the process and then redirect the pipe to a file. Like
mkfifo "tmp.log"
program_a > "tmp.log" &
cat "tmp.log" > "log_$!"
You can't do that from the shell that way because the commandline is created before the program is even called. You have essentially two options:
1) Create the filename and write to it from within the program (easy if it is a shell script)
2) Create a named pipe, background the process and then redirect the pipe to a file. Like
mkfifo "tmp.log"
program_a > "tmp.log" &
cat "tmp.log" > "log_$!"
answered Mar 19 '14 at 9:24
orionorion
9,2801933
9,2801933
Yes, you can.
– Gilles
Mar 19 '14 at 22:33
add a comment |
Yes, you can.
– Gilles
Mar 19 '14 at 22:33
Yes, you can.
– Gilles
Mar 19 '14 at 22:33
Yes, you can.
– Gilles
Mar 19 '14 at 22:33
add a comment |
This doesn't answer the question directly, but I would question why I need to have a file with the pid
in the name. If it is simply a unique filename that you are looking for, then there are more robust ways to do this. Most Unices have a mktemp
command (unfortunately this is not POSIX though). Using GNU mktemp
, you could do:
tmp_file=$(mktemp --tmpdir=. log_XXXXXXXXXX)
program_a >"$tmp_file"
If you have to access the files at a later date, then it may be useful to include the date/time in the filename:
log_file=$(mktemp --tmpdir=. log_"$(date +%F_%T)".XXX)
program_a >"$log_file"
If you are looking to ensure that only one instance of a specific process is running, then on Linux you can use flock
:
(
flock -n 9 || { echo "program_a already running"; exit 1; }
program_a
) 9>/var/lock/program_a
Otherwise, if you are looking to have another program read the output of program_a
while it is still running, then using a file is surely a method of last resort. Much better to use a pipe or a named pipe as per orion's answer.
add a comment |
This doesn't answer the question directly, but I would question why I need to have a file with the pid
in the name. If it is simply a unique filename that you are looking for, then there are more robust ways to do this. Most Unices have a mktemp
command (unfortunately this is not POSIX though). Using GNU mktemp
, you could do:
tmp_file=$(mktemp --tmpdir=. log_XXXXXXXXXX)
program_a >"$tmp_file"
If you have to access the files at a later date, then it may be useful to include the date/time in the filename:
log_file=$(mktemp --tmpdir=. log_"$(date +%F_%T)".XXX)
program_a >"$log_file"
If you are looking to ensure that only one instance of a specific process is running, then on Linux you can use flock
:
(
flock -n 9 || { echo "program_a already running"; exit 1; }
program_a
) 9>/var/lock/program_a
Otherwise, if you are looking to have another program read the output of program_a
while it is still running, then using a file is surely a method of last resort. Much better to use a pipe or a named pipe as per orion's answer.
add a comment |
This doesn't answer the question directly, but I would question why I need to have a file with the pid
in the name. If it is simply a unique filename that you are looking for, then there are more robust ways to do this. Most Unices have a mktemp
command (unfortunately this is not POSIX though). Using GNU mktemp
, you could do:
tmp_file=$(mktemp --tmpdir=. log_XXXXXXXXXX)
program_a >"$tmp_file"
If you have to access the files at a later date, then it may be useful to include the date/time in the filename:
log_file=$(mktemp --tmpdir=. log_"$(date +%F_%T)".XXX)
program_a >"$log_file"
If you are looking to ensure that only one instance of a specific process is running, then on Linux you can use flock
:
(
flock -n 9 || { echo "program_a already running"; exit 1; }
program_a
) 9>/var/lock/program_a
Otherwise, if you are looking to have another program read the output of program_a
while it is still running, then using a file is surely a method of last resort. Much better to use a pipe or a named pipe as per orion's answer.
This doesn't answer the question directly, but I would question why I need to have a file with the pid
in the name. If it is simply a unique filename that you are looking for, then there are more robust ways to do this. Most Unices have a mktemp
command (unfortunately this is not POSIX though). Using GNU mktemp
, you could do:
tmp_file=$(mktemp --tmpdir=. log_XXXXXXXXXX)
program_a >"$tmp_file"
If you have to access the files at a later date, then it may be useful to include the date/time in the filename:
log_file=$(mktemp --tmpdir=. log_"$(date +%F_%T)".XXX)
program_a >"$log_file"
If you are looking to ensure that only one instance of a specific process is running, then on Linux you can use flock
:
(
flock -n 9 || { echo "program_a already running"; exit 1; }
program_a
) 9>/var/lock/program_a
Otherwise, if you are looking to have another program read the output of program_a
while it is still running, then using a file is surely a method of last resort. Much better to use a pipe or a named pipe as per orion's answer.
edited Apr 13 '17 at 12:36
Community♦
1
1
answered Mar 19 '14 at 11:03
GraemeGraeme
25.5k46699
25.5k46699
add a comment |
add a comment |
You can't know the PID until the process has started. So you need to first start the process, then create the log file, then execute the program you want to execute (exec
replaces the calling shell with the given program, it doesn't fork a new process).
sh -c 'exec program_a >log_$$'
$!
is the PID of the last program started in the background and cannot help you here.
Alternatively, you could create the log file under a temporary name, start the program, and then rename the log file, but it's needlessly more complicated.
Is that possible in combination withnohup
? When I put thenohup
command either betweenexec
andprogram_a
or beforesh
, the value of$$
equals to (PID
of theprogram_a instance
) - 1
– stofl
Feb 27 '17 at 22:24
@stofl Sure, you can runnohup sh …
. And indeed$$
is the PID of the new program instance, that was the point of the question. What's the problem?
– Gilles
Feb 27 '17 at 22:33
When I runsh -c 'nohup ./test >log_$$' &
it returns me (right now)9096
. When I callps ax | grep test
, the started process has the PID9097
. I think,nohup
itself is a program that starts a new process detached from the shell and has a different PID because of that. And I think, this difference if1
is not really reliable.
– stofl
Mar 5 '17 at 23:12
1
@stofl You needexec
, otherwisenohup
is a child of the shell and so has a different PID. (Some shells optimize this but not all.)sh -c 'exec nohup ./test >log_$$'
– Gilles
Mar 6 '17 at 0:33
Uh! Yes, that works, thank you. Seems that I have forgotten to write thatexec
in both of my tests!
– stofl
Mar 6 '17 at 18:16
add a comment |
You can't know the PID until the process has started. So you need to first start the process, then create the log file, then execute the program you want to execute (exec
replaces the calling shell with the given program, it doesn't fork a new process).
sh -c 'exec program_a >log_$$'
$!
is the PID of the last program started in the background and cannot help you here.
Alternatively, you could create the log file under a temporary name, start the program, and then rename the log file, but it's needlessly more complicated.
Is that possible in combination withnohup
? When I put thenohup
command either betweenexec
andprogram_a
or beforesh
, the value of$$
equals to (PID
of theprogram_a instance
) - 1
– stofl
Feb 27 '17 at 22:24
@stofl Sure, you can runnohup sh …
. And indeed$$
is the PID of the new program instance, that was the point of the question. What's the problem?
– Gilles
Feb 27 '17 at 22:33
When I runsh -c 'nohup ./test >log_$$' &
it returns me (right now)9096
. When I callps ax | grep test
, the started process has the PID9097
. I think,nohup
itself is a program that starts a new process detached from the shell and has a different PID because of that. And I think, this difference if1
is not really reliable.
– stofl
Mar 5 '17 at 23:12
1
@stofl You needexec
, otherwisenohup
is a child of the shell and so has a different PID. (Some shells optimize this but not all.)sh -c 'exec nohup ./test >log_$$'
– Gilles
Mar 6 '17 at 0:33
Uh! Yes, that works, thank you. Seems that I have forgotten to write thatexec
in both of my tests!
– stofl
Mar 6 '17 at 18:16
add a comment |
You can't know the PID until the process has started. So you need to first start the process, then create the log file, then execute the program you want to execute (exec
replaces the calling shell with the given program, it doesn't fork a new process).
sh -c 'exec program_a >log_$$'
$!
is the PID of the last program started in the background and cannot help you here.
Alternatively, you could create the log file under a temporary name, start the program, and then rename the log file, but it's needlessly more complicated.
You can't know the PID until the process has started. So you need to first start the process, then create the log file, then execute the program you want to execute (exec
replaces the calling shell with the given program, it doesn't fork a new process).
sh -c 'exec program_a >log_$$'
$!
is the PID of the last program started in the background and cannot help you here.
Alternatively, you could create the log file under a temporary name, start the program, and then rename the log file, but it's needlessly more complicated.
answered Mar 19 '14 at 22:33
GillesGilles
546k12911101624
546k12911101624
Is that possible in combination withnohup
? When I put thenohup
command either betweenexec
andprogram_a
or beforesh
, the value of$$
equals to (PID
of theprogram_a instance
) - 1
– stofl
Feb 27 '17 at 22:24
@stofl Sure, you can runnohup sh …
. And indeed$$
is the PID of the new program instance, that was the point of the question. What's the problem?
– Gilles
Feb 27 '17 at 22:33
When I runsh -c 'nohup ./test >log_$$' &
it returns me (right now)9096
. When I callps ax | grep test
, the started process has the PID9097
. I think,nohup
itself is a program that starts a new process detached from the shell and has a different PID because of that. And I think, this difference if1
is not really reliable.
– stofl
Mar 5 '17 at 23:12
1
@stofl You needexec
, otherwisenohup
is a child of the shell and so has a different PID. (Some shells optimize this but not all.)sh -c 'exec nohup ./test >log_$$'
– Gilles
Mar 6 '17 at 0:33
Uh! Yes, that works, thank you. Seems that I have forgotten to write thatexec
in both of my tests!
– stofl
Mar 6 '17 at 18:16
add a comment |
Is that possible in combination withnohup
? When I put thenohup
command either betweenexec
andprogram_a
or beforesh
, the value of$$
equals to (PID
of theprogram_a instance
) - 1
– stofl
Feb 27 '17 at 22:24
@stofl Sure, you can runnohup sh …
. And indeed$$
is the PID of the new program instance, that was the point of the question. What's the problem?
– Gilles
Feb 27 '17 at 22:33
When I runsh -c 'nohup ./test >log_$$' &
it returns me (right now)9096
. When I callps ax | grep test
, the started process has the PID9097
. I think,nohup
itself is a program that starts a new process detached from the shell and has a different PID because of that. And I think, this difference if1
is not really reliable.
– stofl
Mar 5 '17 at 23:12
1
@stofl You needexec
, otherwisenohup
is a child of the shell and so has a different PID. (Some shells optimize this but not all.)sh -c 'exec nohup ./test >log_$$'
– Gilles
Mar 6 '17 at 0:33
Uh! Yes, that works, thank you. Seems that I have forgotten to write thatexec
in both of my tests!
– stofl
Mar 6 '17 at 18:16
Is that possible in combination with
nohup
? When I put the nohup
command either between exec
and program_a
or before sh
, the value of $$
equals to (PID
of the program_a instance
) - 1– stofl
Feb 27 '17 at 22:24
Is that possible in combination with
nohup
? When I put the nohup
command either between exec
and program_a
or before sh
, the value of $$
equals to (PID
of the program_a instance
) - 1– stofl
Feb 27 '17 at 22:24
@stofl Sure, you can run
nohup sh …
. And indeed $$
is the PID of the new program instance, that was the point of the question. What's the problem?– Gilles
Feb 27 '17 at 22:33
@stofl Sure, you can run
nohup sh …
. And indeed $$
is the PID of the new program instance, that was the point of the question. What's the problem?– Gilles
Feb 27 '17 at 22:33
When I run
sh -c 'nohup ./test >log_$$' &
it returns me (right now) 9096
. When I call ps ax | grep test
, the started process has the PID 9097
. I think, nohup
itself is a program that starts a new process detached from the shell and has a different PID because of that. And I think, this difference if 1
is not really reliable.– stofl
Mar 5 '17 at 23:12
When I run
sh -c 'nohup ./test >log_$$' &
it returns me (right now) 9096
. When I call ps ax | grep test
, the started process has the PID 9097
. I think, nohup
itself is a program that starts a new process detached from the shell and has a different PID because of that. And I think, this difference if 1
is not really reliable.– stofl
Mar 5 '17 at 23:12
1
1
@stofl You need
exec
, otherwise nohup
is a child of the shell and so has a different PID. (Some shells optimize this but not all.) sh -c 'exec nohup ./test >log_$$'
– Gilles
Mar 6 '17 at 0:33
@stofl You need
exec
, otherwise nohup
is a child of the shell and so has a different PID. (Some shells optimize this but not all.) sh -c 'exec nohup ./test >log_$$'
– Gilles
Mar 6 '17 at 0:33
Uh! Yes, that works, thank you. Seems that I have forgotten to write that
exec
in both of my tests!– stofl
Mar 6 '17 at 18:16
Uh! Yes, that works, thank you. Seems that I have forgotten to write that
exec
in both of my tests!– stofl
Mar 6 '17 at 18:16
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f120347%2fwrite-program-output-to-log-file-containing-pid-in-its-name%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Is the program a shell script?
– devnull
Mar 19 '14 at 9:23
@devnull Nope its not
– greole
Mar 19 '14 at 9:26