beyondgrep / ack2

**ack 2 is no longer being maintained. ack 3 is the latest version.**
https://github.com/beyondgrep/ack3/
Other
1.48k stars 138 forks source link

ack outputs nothing using crontab in linux #649

Closed zhilongjia closed 7 years ago

zhilongjia commented 7 years ago

ack outputs nothing using crontab in linux.

In the crontab file (edited with sudo crontab -e):

39 20 * * * /ext/test110.sh

And cat /ext/test110.sh will show

#! /bin/sh

/usr/bin/ack "localhost" /etc/hosts > /ext/1.t
 which ack > /ext/2.t
/usr/bin/ack --help > /ext/3.t

After 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, as

`Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES] ...`

If I run ack "localhost" /etc/hosts > /ext/4.t in bash (4.3.30) or sh directly, cat /ext/4.t will output :

127.0.0.1  localhost

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, while grep has none. The example shown above is only for debug. My final aim is to backup all codes in this computer using ack + crontab + git.

Thank you.

n1vux commented 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.

petdance commented 7 years ago

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?

hoelzro commented 7 years ago

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.

hoelzro commented 7 years ago

Using --nofilter works

hoelzro commented 7 years ago

hashbrown-nofilter

n1vux commented 7 years ago

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

n1vux commented 7 years ago

ok, so --nofilter is workaround for the original request.

why is that required, because no tty confuses us ?

petdance commented 7 years ago

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.

hoelzro commented 7 years ago

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?

petdance commented 7 years ago

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.

n1vux commented 7 years ago

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.

zhilongjia commented 7 years ago

--nofilter can make it. Thank you all.

hoelzro commented 7 years ago

@zhilongjia If you're satisfied, would you mind closing this issue?

petdance commented 7 years ago

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.