Echoing a tail command produces unexpected output? Announcing the arrival of Valued Associate...
What does "fit" mean in this sentence?
Sci-Fi book where patients in a coma ward all live in a subconscious world linked together
Output the ŋarâþ crîþ alphabet song without using (m)any letters
What LEGO pieces have "real-world" functionality?
Error "illegal generic type for instanceof" when using local classes
How does the particle を relate to the verb 行く in the structure「A を + B に行く」?
Can a USB port passively 'listen only'?
2001: A Space Odyssey's use of the song "Daisy Bell" (Bicycle Built for Two); life imitates art or vice-versa?
Why did the IBM 650 use bi-quinary?
Why did the Falcon Heavy center core fall off the ASDS OCISLY barge?
Generate an RGB colour grid
How to deal with a team lead who never gives me credit?
How to find out what spells would be useless to a blind NPC spellcaster?
Can a non-EU citizen traveling with me come with me through the EU passport line?
String `!23` is replaced with `docker` in command line
Withdrew £2800, but only £2000 shows as withdrawn on online banking; what are my obligations?
How does debian/ubuntu knows a package has a updated version
When a candle burns, why does the top of wick glow if bottom of flame is hottest?
List *all* the tuples!
What does the "x" in "x86" represent?
What exactly is a "Meth" in Altered Carbon?
What is Arya's weapon design?
Identify plant with long narrow paired leaves and reddish stems
How can I make names more distinctive without making them longer?
Echoing a tail command produces unexpected output?
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
2019 Community Moderator Election Results
Why I closed the “Why is Kali so hard” questionWhy does cron silently fail to run sudo stuff in my script?BashScript works from Terminal but not from CronTabHow to run a shell script using cron and atsh script containing perl element does not produce same output via crontab as manual executionHave a command in my $PATH, but it is not being recognized when I use sudoPiping the result of ls to tailWhy does head; tail on a large file sometimes take a long time and sometimes not?Crontab in Mac is not workingtail and bash: different output when same is expectedCronjob output not working
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
This command, when run alone, produces the expected result (the last line of the crontab):
tail -n 1 /etc/crontab
However, when I run it as part of an echo command to send the result to a file, it adds a summary of all the files in the working directory, plus the expected result:
sudo bash -c 'echo $(tail -n 1 /etc/crontab) > /path/to/file'
Why did this command produce the extra data?
bash sudo cron echo tail
New contributor
add a comment |
This command, when run alone, produces the expected result (the last line of the crontab):
tail -n 1 /etc/crontab
However, when I run it as part of an echo command to send the result to a file, it adds a summary of all the files in the working directory, plus the expected result:
sudo bash -c 'echo $(tail -n 1 /etc/crontab) > /path/to/file'
Why did this command produce the extra data?
bash sudo cron echo tail
New contributor
2
See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?
– Stéphane Chazelas
19 hours ago
3
What isecho
doing for you here? Consider alsotail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null
– ctrl-alt-delor
17 hours ago
1
What is wrong withecho $(stuff)
?
– Kamil Maciorowski
13 hours ago
add a comment |
This command, when run alone, produces the expected result (the last line of the crontab):
tail -n 1 /etc/crontab
However, when I run it as part of an echo command to send the result to a file, it adds a summary of all the files in the working directory, plus the expected result:
sudo bash -c 'echo $(tail -n 1 /etc/crontab) > /path/to/file'
Why did this command produce the extra data?
bash sudo cron echo tail
New contributor
This command, when run alone, produces the expected result (the last line of the crontab):
tail -n 1 /etc/crontab
However, when I run it as part of an echo command to send the result to a file, it adds a summary of all the files in the working directory, plus the expected result:
sudo bash -c 'echo $(tail -n 1 /etc/crontab) > /path/to/file'
Why did this command produce the extra data?
bash sudo cron echo tail
bash sudo cron echo tail
New contributor
New contributor
edited 13 hours ago
Jeff Schaller♦
45.1k1164147
45.1k1164147
New contributor
asked 19 hours ago
DavidwDavidw
1416
1416
New contributor
New contributor
2
See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?
– Stéphane Chazelas
19 hours ago
3
What isecho
doing for you here? Consider alsotail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null
– ctrl-alt-delor
17 hours ago
1
What is wrong withecho $(stuff)
?
– Kamil Maciorowski
13 hours ago
add a comment |
2
See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?
– Stéphane Chazelas
19 hours ago
3
What isecho
doing for you here? Consider alsotail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null
– ctrl-alt-delor
17 hours ago
1
What is wrong withecho $(stuff)
?
– Kamil Maciorowski
13 hours ago
2
2
See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?
– Stéphane Chazelas
19 hours ago
See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?
– Stéphane Chazelas
19 hours ago
3
3
What is
echo
doing for you here? Consider also tail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null
– ctrl-alt-delor
17 hours ago
What is
echo
doing for you here? Consider also tail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null
– ctrl-alt-delor
17 hours ago
1
1
What is wrong with
echo $(stuff)
?– Kamil Maciorowski
13 hours ago
What is wrong with
echo $(stuff)
?– Kamil Maciorowski
13 hours ago
add a comment |
3 Answers
3
active
oldest
votes
Your crontab line has one or more asterisks *
in it, indicating "any time". When that line is substituted in from the command substitution, the result is something like
echo * * * * * cmd > /path/to/file
While most further expansions are not applied to the output of command substitution, pathname expansion is (as is field splitting):
The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.
Pathname expansion is what turns *.txt
into a list of matching filenames (globbing), where *
matches everything. The end result is that you get every (non-hidden) filename in the working directory listed for every *
in your crontab line.
You could fix this by quoting the expansion, if the code you posted was a representative of a more complex command:
sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'
but more straightforwardly just lose the echo
entirely:
sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'
This should do what you want and it's simpler as well (the only other material difference is that this version will omit field splitting that would otherwise have occurred, so runs of spaces won't be collapsed).
4
Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary:tail -n -1 /etc/crontab | sudo tee /path/to/file
is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.
– Bass
18 hours ago
add a comment |
Let's consider a directory with these files:
$ ls
crontab file1 file2 file3
$ cat crontab
f*
Now, let's run the tail command:
$ tail -n 1 crontab
f*
The above is the last line of crontab
and this is what we expect. However:
$ echo $(tail -n 1 crontab)
file1 file2 file3
Double-quotes eliminate this problem:
$ echo "$(tail -n 1 crontab)"
f*
Without the double-quotes, the result of the command substitution is expanded by the shell. One of the expansions is pathname expansion. In the case above, this means that f*
is expanded to match every file name that starts with f
.
Unless you explicitly want shell expansions, put all you shell variables and/or command substitutions inside double quotes.
add a comment |
globing shell mecanism will expand *
to local file.
crontab line is likely to have a *
as placeholder for any.
e.g. this line in crontab run on 7.47 am on sunday, first star mean any day, second any month.
47 7 * * 0 /run/on/sunday
then you tail
, and issue
echo 47 7 * * 0 /run/on/sunday
that will expand *
to local file.
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
});
}
});
Davidw is a new contributor. Be nice, and check out our Code of Conduct.
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%2f512702%2fechoing-a-tail-command-produces-unexpected-output%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your crontab line has one or more asterisks *
in it, indicating "any time". When that line is substituted in from the command substitution, the result is something like
echo * * * * * cmd > /path/to/file
While most further expansions are not applied to the output of command substitution, pathname expansion is (as is field splitting):
The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.
Pathname expansion is what turns *.txt
into a list of matching filenames (globbing), where *
matches everything. The end result is that you get every (non-hidden) filename in the working directory listed for every *
in your crontab line.
You could fix this by quoting the expansion, if the code you posted was a representative of a more complex command:
sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'
but more straightforwardly just lose the echo
entirely:
sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'
This should do what you want and it's simpler as well (the only other material difference is that this version will omit field splitting that would otherwise have occurred, so runs of spaces won't be collapsed).
4
Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary:tail -n -1 /etc/crontab | sudo tee /path/to/file
is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.
– Bass
18 hours ago
add a comment |
Your crontab line has one or more asterisks *
in it, indicating "any time". When that line is substituted in from the command substitution, the result is something like
echo * * * * * cmd > /path/to/file
While most further expansions are not applied to the output of command substitution, pathname expansion is (as is field splitting):
The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.
Pathname expansion is what turns *.txt
into a list of matching filenames (globbing), where *
matches everything. The end result is that you get every (non-hidden) filename in the working directory listed for every *
in your crontab line.
You could fix this by quoting the expansion, if the code you posted was a representative of a more complex command:
sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'
but more straightforwardly just lose the echo
entirely:
sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'
This should do what you want and it's simpler as well (the only other material difference is that this version will omit field splitting that would otherwise have occurred, so runs of spaces won't be collapsed).
4
Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary:tail -n -1 /etc/crontab | sudo tee /path/to/file
is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.
– Bass
18 hours ago
add a comment |
Your crontab line has one or more asterisks *
in it, indicating "any time". When that line is substituted in from the command substitution, the result is something like
echo * * * * * cmd > /path/to/file
While most further expansions are not applied to the output of command substitution, pathname expansion is (as is field splitting):
The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.
Pathname expansion is what turns *.txt
into a list of matching filenames (globbing), where *
matches everything. The end result is that you get every (non-hidden) filename in the working directory listed for every *
in your crontab line.
You could fix this by quoting the expansion, if the code you posted was a representative of a more complex command:
sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'
but more straightforwardly just lose the echo
entirely:
sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'
This should do what you want and it's simpler as well (the only other material difference is that this version will omit field splitting that would otherwise have occurred, so runs of spaces won't be collapsed).
Your crontab line has one or more asterisks *
in it, indicating "any time". When that line is substituted in from the command substitution, the result is something like
echo * * * * * cmd > /path/to/file
While most further expansions are not applied to the output of command substitution, pathname expansion is (as is field splitting):
The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.
Pathname expansion is what turns *.txt
into a list of matching filenames (globbing), where *
matches everything. The end result is that you get every (non-hidden) filename in the working directory listed for every *
in your crontab line.
You could fix this by quoting the expansion, if the code you posted was a representative of a more complex command:
sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'
but more straightforwardly just lose the echo
entirely:
sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'
This should do what you want and it's simpler as well (the only other material difference is that this version will omit field splitting that would otherwise have occurred, so runs of spaces won't be collapsed).
edited 19 hours ago
answered 19 hours ago
Michael HomerMichael Homer
51.2k8142179
51.2k8142179
4
Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary:tail -n -1 /etc/crontab | sudo tee /path/to/file
is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.
– Bass
18 hours ago
add a comment |
4
Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary:tail -n -1 /etc/crontab | sudo tee /path/to/file
is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.
– Bass
18 hours ago
4
4
Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary:
tail -n -1 /etc/crontab | sudo tee /path/to/file
is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.– Bass
18 hours ago
Since /etc/crontab is almost always world readable, all the "bash -c" trickery is actually unnecessary:
tail -n -1 /etc/crontab | sudo tee /path/to/file
is the idiom that I've found to be the least error prone when redirecting output into files that require superuser privileges.– Bass
18 hours ago
add a comment |
Let's consider a directory with these files:
$ ls
crontab file1 file2 file3
$ cat crontab
f*
Now, let's run the tail command:
$ tail -n 1 crontab
f*
The above is the last line of crontab
and this is what we expect. However:
$ echo $(tail -n 1 crontab)
file1 file2 file3
Double-quotes eliminate this problem:
$ echo "$(tail -n 1 crontab)"
f*
Without the double-quotes, the result of the command substitution is expanded by the shell. One of the expansions is pathname expansion. In the case above, this means that f*
is expanded to match every file name that starts with f
.
Unless you explicitly want shell expansions, put all you shell variables and/or command substitutions inside double quotes.
add a comment |
Let's consider a directory with these files:
$ ls
crontab file1 file2 file3
$ cat crontab
f*
Now, let's run the tail command:
$ tail -n 1 crontab
f*
The above is the last line of crontab
and this is what we expect. However:
$ echo $(tail -n 1 crontab)
file1 file2 file3
Double-quotes eliminate this problem:
$ echo "$(tail -n 1 crontab)"
f*
Without the double-quotes, the result of the command substitution is expanded by the shell. One of the expansions is pathname expansion. In the case above, this means that f*
is expanded to match every file name that starts with f
.
Unless you explicitly want shell expansions, put all you shell variables and/or command substitutions inside double quotes.
add a comment |
Let's consider a directory with these files:
$ ls
crontab file1 file2 file3
$ cat crontab
f*
Now, let's run the tail command:
$ tail -n 1 crontab
f*
The above is the last line of crontab
and this is what we expect. However:
$ echo $(tail -n 1 crontab)
file1 file2 file3
Double-quotes eliminate this problem:
$ echo "$(tail -n 1 crontab)"
f*
Without the double-quotes, the result of the command substitution is expanded by the shell. One of the expansions is pathname expansion. In the case above, this means that f*
is expanded to match every file name that starts with f
.
Unless you explicitly want shell expansions, put all you shell variables and/or command substitutions inside double quotes.
Let's consider a directory with these files:
$ ls
crontab file1 file2 file3
$ cat crontab
f*
Now, let's run the tail command:
$ tail -n 1 crontab
f*
The above is the last line of crontab
and this is what we expect. However:
$ echo $(tail -n 1 crontab)
file1 file2 file3
Double-quotes eliminate this problem:
$ echo "$(tail -n 1 crontab)"
f*
Without the double-quotes, the result of the command substitution is expanded by the shell. One of the expansions is pathname expansion. In the case above, this means that f*
is expanded to match every file name that starts with f
.
Unless you explicitly want shell expansions, put all you shell variables and/or command substitutions inside double quotes.
answered 19 hours ago
John1024John1024
48.8k5114129
48.8k5114129
add a comment |
add a comment |
globing shell mecanism will expand *
to local file.
crontab line is likely to have a *
as placeholder for any.
e.g. this line in crontab run on 7.47 am on sunday, first star mean any day, second any month.
47 7 * * 0 /run/on/sunday
then you tail
, and issue
echo 47 7 * * 0 /run/on/sunday
that will expand *
to local file.
add a comment |
globing shell mecanism will expand *
to local file.
crontab line is likely to have a *
as placeholder for any.
e.g. this line in crontab run on 7.47 am on sunday, first star mean any day, second any month.
47 7 * * 0 /run/on/sunday
then you tail
, and issue
echo 47 7 * * 0 /run/on/sunday
that will expand *
to local file.
add a comment |
globing shell mecanism will expand *
to local file.
crontab line is likely to have a *
as placeholder for any.
e.g. this line in crontab run on 7.47 am on sunday, first star mean any day, second any month.
47 7 * * 0 /run/on/sunday
then you tail
, and issue
echo 47 7 * * 0 /run/on/sunday
that will expand *
to local file.
globing shell mecanism will expand *
to local file.
crontab line is likely to have a *
as placeholder for any.
e.g. this line in crontab run on 7.47 am on sunday, first star mean any day, second any month.
47 7 * * 0 /run/on/sunday
then you tail
, and issue
echo 47 7 * * 0 /run/on/sunday
that will expand *
to local file.
answered 19 hours ago
ArchemarArchemar
20.6k93973
20.6k93973
add a comment |
add a comment |
Davidw is a new contributor. Be nice, and check out our Code of Conduct.
Davidw is a new contributor. Be nice, and check out our Code of Conduct.
Davidw is a new contributor. Be nice, and check out our Code of Conduct.
Davidw is a new contributor. Be nice, and check out our Code of Conduct.
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%2f512702%2fechoing-a-tail-command-produces-unexpected-output%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
2
See Why does my shell script choke on whitespace or other special characters? and Why is printf better than echo?
– Stéphane Chazelas
19 hours ago
3
What is
echo
doing for you here? Consider alsotail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null
– ctrl-alt-delor
17 hours ago
1
What is wrong with
echo $(stuff)
?– Kamil Maciorowski
13 hours ago