Closed zhilongjia closed 7 years ago
Andy guessed in initial emails
My first guess would be that for some reason root’s pathing can’t see ack, or maybe can’t find the perl that ack needs.
You are correct. 'crontab' runs a very slim environment, even for non-root users.
The entire output of env
in a non-root crontab is
HOME=/home/wdr
LOGNAME=wdr
PATH=/usr/bin:/bin
LANG=en_US.UTF-8
SHELL=/bin/sh
PWD=/home/wdr
If you want to run interpretative programs other than SHELL in crontab, you have to set up all the environment.
I could show you how to set the ENV in your shellscript to make Perl and thus Ack happy, but if you need to run this in the root crontab, you should specify exactly what you want , not rely on magic, and use grep, for safety.
What happens if you just run
/usr/bin/ack --help
The question is: Is ack running at all, or is it running, but not giving any output?
Can confirm - fun fact, though: this works:
* * * * * ack localhost localhost /etc/hosts </dev/null > /tmp/test-output
I'm guessing it's ack's pipe detection that's tripping things up.
Using --nofilter
works
I am reproducing with personal not root crontab.
- 21 * /home/wdr/tmp/cron-test > /tmp/$$.ack
!/bin/sh
date
env
/home/wdr/bin/ack2 --version
/home/wdr/bin/ack2 --help
echo foo | /home/wdr/bin/ack2 foo
/home/wdr/bin/ack2 localhost /etc/hosts
echo grep next
grep localhost /etc/hosts
output
Thu Sep 14 21:59:01 EDT 2017
HOME=/home/wdr
LOGNAME=wdr
PATH=/usr/bin:/bin
LANG=en_US.UTF-8
SHELL=/bin/sh
PWD=/home/wdr
ack 2.15_03
Running under Perl 5.22.1 at /usr/bin/perl
Copyright 2005-2017 Andy Lester.
This program is free software. You may modify or distribute it
under the terms of the Artistic License v2.0.
Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES]
Search for PATTERN in each source file in the tree from the current
directory on down. If any files or directories are specified, then
only those files and directories are checked. ack may also search
STDIN, but only if no file or directory arguments are specified,
or if one of them is "-".
Default switches may be specified in ACK_OPTIONS environment variable or
an .ackrc file. If you want no dependency on the environment, turn it
off with --noenv.
Example: ack -i select
Searching:
-i, --ignore-case Ignore case distinctions in PATTERN
--[no]smart-case Ignore case distinctions in PATTERN,
only if PATTERN contains no upper case.
Ignored if -i is specified
-v, --invert-match Invert match: select non-matching lines
-w, --word-regexp Force PATTERN to match only whole words
-Q, --literal Quote all metacharacters; PATTERN is literal
Search output:
--lines=NUM Only print line(s) NUM of each file
-l, --files-with-matches Only print filenames containing matches
-L, --files-without-matches Only print filenames with no matches
--output=expr Output the evaluation of expr for each line
(turns off text highlighting)
-o Show only the part of a line matching PATTERN
Same as --output='$&'
--passthru Print all lines, whether matching or not
--match PATTERN Specify PATTERN explicitly.
-m, --max-count=NUM Stop searching in each file after NUM matches
-1 Stop searching after one match of any kind
-H, --with-filename Print the filename for each match (default:
on unless explicitly searching a single file)
-h, --no-filename Suppress the prefixing filename on output
-c, --count Show number of lines matching per file
--[no]column Show the column number of the first match
-A NUM, --after-context=NUM Print NUM lines of trailing context after
matching lines.
-B NUM, --before-context=NUM Print NUM lines of leading context before
matching lines.
-C [NUM], --context[=NUM] Print NUM lines (default 2) of output context.
--print0 Print null byte as separator between filenames,
only works with -f, -g, -l, -L or -c.
-s Suppress error messages about nonexistent or
unreadable files.
File presentation:
--pager=COMMAND Pipes all ack output through COMMAND. For
example, --pager="less -R". Ignored if output
is redirected.
--nopager Do not send output through a pager. Cancels
any setting in ~/.ackrc, ACK_PAGER or
ACK_PAGER_COLOR.
--[no]heading Print a filename heading above each file's
results. (default: on when used interactively)
--[no]break Print a break between results from different
files. (default: on when used interactively)
--group Same as --heading --break
--nogroup Same as --noheading --nobreak
--[no]color Highlight the matching text (default: on unless
output is redirected, or on Windows)
--[no]colour Same as --[no]color
--color-filename=COLOR
--color-match=COLOR
--color-lineno=COLOR Set the color for filenames, matches, and line
numbers.
--flush Flush output immediately, even when ack is used
non-interactively (when output goes to a pipe or
file).
File finding:
-f Only print the files selected, without
searching. The PATTERN must not be specified.
-g Same as -f, but only select files matching
PATTERN.
--sort-files Sort the found files lexically.
--show-types Show which types each file has.
--files-from=FILE Read the list of files to search from FILE.
-x Read the list of files to search from STDIN.
File inclusion/exclusion:
--[no]ignore-dir=name Add/remove directory from list of ignored dirs
--[no]ignore-directory=name Synonym for ignore-dir
--ignore-file=filter Add filter for ignoring files
-r, -R, --recurse Recurse into subdirectories (default: on)
-n, --no-recurse No descending into subdirectories
--[no]follow Follow symlinks. Default is off.
-k, --known-types Include only files of types that ack recognizes.
--type=X Include only X files, where X is a recognized
filetype.
--type=noX Exclude X files.
See "ack --help-types" for supported filetypes.
File type specification:
--type-set TYPE:FILTER:FILTERARGS
Files with the given FILTERARGS applied to the
given FILTER are recognized as being of type
TYPE. This replaces an existing definition for
type TYPE.
--type-add TYPE:FILTER:FILTERARGS
Files with the given FILTERARGS applied to the
given FILTER are recognized as being type TYPE.
--type-del TYPE Removes all filters associated with TYPE.
Miscellaneous:
--[no]env Ignore environment variables and global ackrc
files. --env is legal but redundant.
--ackrc=filename Specify an ackrc file to use
--ignore-ack-defaults Ignore default definitions included with ack.
--create-ackrc Outputs a default ackrc for your customization
to standard output.
--help, -? This help
--help-types Display all known types
--dump Dump information on which options are loaded
from which RC files
--[no]filter Force ack to treat standard input as a pipe
(--filter) or tty (--nofilter)
--man Man page
--version Display version & copyright
--thpppt Bill the Cat
--bar The warning admiral
--cathy Chocolate! Chocolate! Chocolate!
Exit status is 0 if match, 1 if no match.
ack's home page is at http://beyondgrep.com/
The full ack manual is available by running "ack --man".
This is version 2.15_03 of ack. Run "ack --version" for full version info.
foo
grep next
127.0.0.1 localhost
::1 ip6-localhost ip6-loopback
ack runs --version
and --help
and even filters stdin ok, but not with a filename.
Hmm i see Rob says similar
ok, so --nofilter
is workaround for the original request.
why is that required, because no tty confuses us ?
why is that required, because no tty confuses us ?
It has always been so. There is no solution that will make everyone happy in all cases.
If ack detects that standard input isn't a tty, it assumes it's a pipe or file redirect and tries to filter that instead.
To be honest, we should probably warn or something when specifying a filename argument and using ack in filter mode. Can anyone think of a situation in which this would make sense?
To be honest, we should probably warn or something when specifying a filename argument and using ack in filter mode. Can anyone think of a situation in which this would make sense?
I think we went down that road once, but I don't remember specifics. I agree it sounds like the thing to do.
hmm this does sound familiar.
crontab and nohup are common usecases for shell (and thus grep) to run TTY-less but pipe-less.
If we are going to insist on --nofilter instead of DWIM here, we can't count on STDERR going where they'll look for error message.
--nofilter
can make it. Thank you all.
@zhilongjia If you're satisfied, would you mind closing this issue?
We should put something in the FAQ about ack's behavior re: filter mode detection.
On Sep 15, 2017, at 5:10 PM, Rob Hoelz notifications@github.com wrote:
@zhilongjia If you're satisfied, would you mind closing this issue?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.
ack outputs nothing using crontab in linux.
In the crontab file (edited with sudo crontab -e):
And
cat /ext/test110.sh
will showAfter cron, there are 1.t, 2.t and 3.t in
/ext
.cat 1.t
will show nothing, which means/ext/1.t
is created only with no content.cat 2.t
will output/usr/bin/ack
.cat 3.t
will output the whole help, asIf I run
ack "localhost" /etc/hosts > /ext/4.t
in bash (4.3.30) or sh directly,cat /ext/4.t
will output :It seems ack cannot work with cron. where is the bug? BTW,
grep
works on this situation. Thank you.uname -a:
Linux xxx 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64 GNU/Linux
ack --version :ack 2.14, Running under Perl 5.20.2 at /usr/bin/perl
I use
ack
as the--rr
or--python
options, whilegrep
has none. The example shown above is only for debug. My final aim is to backup all codes in this computer usingack + crontab + git
.Thank you.