1

I am looking for a way to create a customized function in one of the setting files, so that when I open up a new session, the same customized function can be evaluated (or sourced), and I can use the function easily.

I try to create a function to check if ERROR exists in my log file, so when I check the log files, I can just type the function name and the log file name. Now I am using grep:grep ERROR test.txt

But I want to make it easier because I have a lot of these checks. So I add this line in .bashrc:

ok(){grep ERROR $filename}

and when I use the function, I expected to type: ok test.txt and it should give me the ERROR lines, if any.

However, after I evaluated the .bashrc file, I got an error message:

-bash: .bashrc: line 16: syntax error: unexpected end of file

After I typed: ok test.txt, it provides:

-bash: ok: command not found

Can someone help me with this customized function? Or should I paste my code in another setting file like .bashrc-profile?

Thanks a lot in advance!

5

The shell is just really picky about the syntax and whitespace with the { ... } construct. These two ways to set up that function would work:

ok() { grep ERROR $filename; }
ok() {
    grep ERROR $filename
}

Regarding braces { .. } vs. parenthesis ( .. ), Bash's manual states that:

The semicolon (or newline) following list is required.

and

The braces are reserved words, so they must be separated from the list by blanks or other shell metacharacters.

List refers to the commands inside the braces, and all of this applies where ever { ... } is used, but functions are probably the most common place.

Also, if you want to be able to give the filename as a parameter to the function, use $1 inside it. i.e. ok() { grep ERROR "$1"; } could be used as ok test.txt.

  • Thank you so much @ilkkachu. I tried all your suggested scripts. The first two took a long time to run, which shouldn't, because the test file is really small with less than 100 characters. The last one `ok() { grep ERROR "$1"; } works perfect. Do you know why the first two run forever? – Counter10000 Feb 15 '18 at 20:34
  • 2
    grep ERROR $filename with $filename unset will expand to and run grep ERROR, which waits for keyboard input. It doesn't just "take a long time to run", it will never terminate unless you type and end with a flush (usually Ctrl-D). – dhag Feb 15 '18 at 20:41
  • 2
    @Counter10000, a command like grep ERROR $filename would expand the variable filename, and run grep on that file. But if the variable is not set, grep doesn't get a filename, and starts reading standard input, i.e. the terminal instead. grep ERROR "$filename" (with quotes) would give an error instead, since it'd pass grep an empty string as argument, and that's an invalid filename – ilkkachu Feb 15 '18 at 20:42
  • @dhag .@ilkkachu Thank you both. I thought when I put a dollar sign $ in front of a string can make it a variable like $1. But $filename is easier for me to remember that this is a variable about the the file name. That's why I named it $filename. Can I do this? Or I can only use numbers for variables names in .bashrc, such as $1, $101, $9999? – Counter10000 Feb 15 '18 at 20:46
  • 1
    @Counter10000, regular variables have names like filename, but the arguments to a function or script show up in the so-called positional parameters, and they're the numbered ones, $1, $2, .... (they don't have names, unlike function parameters in real programming languages.) see e.g. mywiki.wooledge.org/BashGuide/Parameters and mywiki.wooledge.org/BashGuide/CompoundCommands#Functions – ilkkachu Feb 15 '18 at 20:56
0

don't have to be so, you'd feel free and much benefit of it

ok() { set -f
if test -z "$2"
then
  grep -HPine "$1" -r --include=*.log --include=*.txt
else
  grep -HPine "$1" -r --include="$2"
fi
}

$ ok error test.txt
$ ok err test.txt
$ ok error
$ ok 'err|warn'
$ ok error logdata.*

the 3rd usage will find all lines having 'error' string in all files with log and txt extension across all directories in current directory
the 4th will find all lines having 'error' or 'warn' string in all files with log and txt extension across all directories in current directory
the 5th will find all lines having 'error' string in all files named logdata with any extension name across all directories in current directory

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.