I have come across a bash script which contains the commands:
cd .git/hooks
[ `eval ls -l | grep -io 'Post-Commit' | wc -l` -eq 1 ] && echo 'post-commit file check... Pass' || echo 'post-commit file check... Fail'
I believe it is to check for a file named post-commit
in the .git/hooks
folder. But even if I create the file post-commit
inside the directory I get the output as: post-commit file check... Fail
.
Am I doing something wrong here? I create my file using:
cat > post-commit
and then I write into it and make it into an executable using chmod +x post-commit
Any help will be really appreciated
Although this script seems to be aimed at Git hooks, it has no dependency on Git in any way, so I dropped the git and githooks tags. It also has nothing to do with Linux so I dropped the linux tag.
The eval
here is entirely unnecessary. 1 We can drop it:
[ `ls -l | grep -io 'Post-Commit' | wc -l` -eq 1 ] &&
echo 'post-commit file check... Pass' ||
echo 'post-commit file check... Fail'
(I broke this into more lines for readability).
As Losko notes in a comment , [
is nominally an external command. In practice it's actually built into most shells, including bash, so that there's no fork-and-exec.
The backquoted section, however, does require a fork-and-exec. Text of the form `command`
is more or less equivalent to code of the form $(command)
. The $(...)
form is generally superior because it provides sane nesting, so if there's a choice of which to use, one should usually prefer the $(...)
form. In any case, it just means: run the command shown and insert its output here . So we're going to run:
ls -l | grep -io 'Post-Commit' | wc -l
as metallic notes in another comment .
The ls -l
does the obvious: a long listing.
The grep -io
has two flags: -i
, meaning ignore case , and -o
, meaning show only the matched part as output . So this is going to look for ls -l
output in which the line contains POST-COMMIT
, post-commit
, pOSt-COMmit
, and so on.
The wc -l
does the obvious: count lines.
The end result is that we count the number of files that have this string in their file name. A file named this-GETS-RUN-post-COMMIThaste-er
for instance gets counted.
The final result of this count gets compared for numeric equality to 1
. If the number is one, the &&
part of the clause is run; if not, the ||
part is run.
Overall, this script fails to do anything useful, because it's too sloppy. It allows mixed-case file names; Git does not. (However, on file systems where the OS allows case-insensitive matching of file names, Git's use of strictly lowercase results in accessing mixed-case or uppercase names after all.) If we find two or more files that match, it complains, yet files whose names simply have a sub -match are probably not an issue here.
1 An eval
in a shell command makes the shell do various expansions first, then run the command. Where it's useful—eg, eval $cmd
—it's also generally pretty dangerous: you must exercise extremely strict control over what goes in $cmd
. Where there are no expansions, as in this case, it's useless. Avoid it as much as possible.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.