LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   backticks not working anymore (https://www.linuxquestions.org/questions/linux-newbie-8/backticks-not-working-anymore-4175678393/)

lostinxlation 07-08-2020 10:01 PM

backticks not working anymore
 
hi
I have been using `command` (with backticks) heavily for many years, but I recently discovered it didn't work anymore.

the following worked before, but not anymore on tcsh.
> grep abc `find . -name "*" -type f -print`


Q&As on some websites say `command` and $(command) are same, and I tried grep abc $(find . -name "*" -print), but it didn't work either.

What's the alternative of `command` on tcsh ?

berndbausch 07-08-2020 10:48 PM

I don't know tcsh, but according to a short web search it uses backticks, not $().

Now why backticks don't work in your case is hard to say, because you don't tell us what you mean by "doesn't work". What do you expect to happen when you enter the command, and what happens? Do you get error messages? Are you sure there are regular files in this directory structure?

chrism01 07-09-2020 12:54 AM

i don't know about tcsh per se, but I always use single (regular) quotes here
Code:

# so not
-name "*"

# but
-name '*'

to prevent interpolation by the shell & instead force the find cmd to handle the '*'.
This is useful generally (& what you really mean ) and in particular solves the 'Too many args' error in dirs with very large nums of files.

Turbocapitalist 07-09-2020 01:35 AM

Quote:

Originally Posted by lostinxlation (Post 6143226)
the following worked before, but not anymore on tcsh.
> grep abc `find . -name "*" -type f -print`

It seems strange that there are reports of it having worked. Normally you'd have to pipe the output of find into grep

Code:

find . -type f -print | grep 'abc'
However, you can offload the work onto find and omit the grep which is then redundant.

Code:

find . -type f -name '*abc*' -print
Remember that there is an implied logical AND between each option unless an OR is specified explicitly. Also, find can do certain type of regular expression pattern matching, though not up to the level which grep can. See "man find".

berndbausch 07-09-2020 03:07 AM

Quote:

Originally Posted by Turbocapitalist (Post 6143267)
Code:

find . -type f -name '*abc*' -print

But this:
Code:

grep abc `find . -name "*" -type f -print`
is quite valid and something else. It means grepping abc in all the files found.

shruggy 07-09-2020 03:16 AM

IMO, the -exec action of find is the right way to do it:
Code:

find -name \* -type f -exec grep -H abc {} +
But in this particular case, grep by itself will also do:
Code:

grep -r abc *
Although I would rather use ack or ag for this.

berndbausch 07-09-2020 03:47 AM

Quote:

Originally Posted by shruggy (Post 6143287)
But in this particular case, grep by itself will also do:
Code:

grep -r abc *

Not quite. It includes files whose names start with a dot, whereas the find command doesn't.

shruggy 07-09-2020 04:34 AM

I'm not sure about it. On my system, they both search in dotfiles. ack also searches in most dotfiles, but ignores some of them, and the list is configurable:
Quote:

The default options for ack ignore certain files and directories. These include:
  • Backup files: Files matching #*# or ending with ~.
  • Coredumps: Files matching core.\d+
  • Version control directories like .svn and .git.


rtmistler 07-09-2020 07:11 AM

I also can't explain the subtleties as to why it doesn't work, or if it should not have previously worked.

Isn't what you wrote (other forms also shown) the same as?
Code:

$ find -type f "*" -exec grep abc {} /dev/null \;
I'd probably use sudo due to the wildcard there, but just style differences. I guess my thinking is that there have been so many changes to things over the years, I go with the flow, and however a shell behaves is just something I deal with, the various times I encounter a uniqueness such as this. I'm neither a shell designer, or much into shell programming, I just use some scripts when they help, or use the shell as best as I can. And it's been so long since I've had something other than bash.

lostinxlation 07-09-2020 05:04 PM

Thank you all.

I did some more experiments and found some interesting behaviors.
First, whether being on bash or tcsh doesn't seem to be a primary cause of the problem. Even on tcsh, the behavior varies.


The followings are experiments I did.
All were done under the directory, /tmp/ICC2/REF/scripts and its subdirectory(you can see the current directory at the shell prompt) on tcsh.



The 1st one doesn't return any matching result, but when I change dir to one of the subdirectories and run the same command, it finds matching lines.

$> /tmp/ICC2/REF/scripts : grep host `find . -name "*" -type f -print`
grep: No match.

$> /tmp/ICC2/REF/scripts : cd N7_H240_reference_script

$> /tmp/ICC2/REF/scripts/N7_H240_reference_script : grep host `find . -name "*" -type f -print`
./scr/project_setup.tcl:set_host_options -max_core 8
./scr/common_setting.tcl:set_host_options -max_core 8
./scr/a/b:host host




THIs is on a company system and I have no control over when and what to be installed or upgraded, so something must have been changed with the system, but the inconsistent results bother me.

MadeInGermany 07-09-2020 06:00 PM

Code:

grep -H abc `find . -name "*" -type f`
does not work with special characters in filenames. The shell breaks space characters into different arguments, and expands wildcards * ? [ ]
Further it can overflow with "too many arguments".

Better take the robust version (from shruggy)
Code:

find . -name "*" -type f -exec grep -H abc {} +
Now find directly passes the filenames to grep without involving the shell.
Also correct but slower is (what rtmistler attempted)
Code:

find . -name "*" -type f -exec grep -H abc {} \;

berndbausch 07-09-2020 06:24 PM

Quote:

Originally Posted by lostinxlation (Post 6143586)
The 1st one doesn't return any matching result, but when I change dir to one of the subdirectories and run the same command, it finds matching lines.

As a first step to solve this, I would look at the two outputs of the find command to see if they contain anything that might change grep's behaviour, such as file names that start with a dash.

Or more realistically, perhaps the output of the first find is too long, though if it were bash I'd expect to see an error message in this case.

pan64 07-10-2020 03:08 AM

I would say you can simply omit -name "*".
Saying backtick does not work is just wrong. It does work as it is expected, also find and grep works. The problem is that your oneliner does not do what you expected.
Most probably because something has been changed in that directory [somewhere inside].
As it was mentioned check what was found by that find command - without grep (if the result was what you need).

lostinxlation 07-12-2020 12:55 AM

Found a cause.
It was because one of the files in the directory tree the find command searches through was named with special characters and i think when grep command was run on that file, it went wrong and produced no result.

rnturn 07-12-2020 04:17 PM

Quote:

Originally Posted by lostinxlation (Post 6143226)
the following worked before, but not anymore on tcsh.
> grep abc `find . -name "*" -type f -print`

I'd be surprised if this command didn't routinely result in an "grep: Argument list too long" error.

lostinxlation 07-13-2020 01:58 AM

Quote:

Originally Posted by rnturn (Post 6144696)
I'd be surprised if this command didn't routinely result in an "grep: Argument list too long" error.

It doesn't unless there are way too many files involved.


All times are GMT -5. The time now is 01:20 AM.