grep -r "string" * error: unrecognized option `--DIRAC3LE--'? - macos

I'm trying to use grep in my Mac Terminal window, and it's giving me that error message. What is that? I've never seen it before and Google is not helping. Looks like DIRAC3LE is some kind of Mac audio plugin -- but why would that interfere with grep?!? Thanks for any help!

Your shell is probably expanding * and there is a '--DIRAC3LE--' in the working directory. grep is then confusing the leading -- with command line options.
Try using
grep -r "string" .
This will recursively search for everything in the working directory.
Also try using "--" before the *. POSIX commands use this to indicate the end of the command line options to prevent such ambiguity (see comments for a reference).

Related

Confusion about using shell pipes from vim command mode

I have a function (written below; source: TeX SX) that uses pipes in the shell which I'd like to use in vim command mode. It works as intended from the shell but returns an E34: No previous command error if entered in vim command mode. Full credit goes to jirislav in this post on TeX SX.
: | pdflatex -halt-on-error src.tex | grep '^!.*' -A200 --color=always
I'd very much like to have this shell functionality from the vim command line if anyone can help with that.
I tried the following from within vim command mode:
:! : | pdflatex -halt-on-error src.tex | grep '^!.*' -A200 --color=always
returns the E34 error. No pipes hides all compilation; however, it also doesn't output errors. Deleting 1 of 2 of the pipes also returns E34 errors for me.
I tried further troubleshooting to no success and here are some results of that. The help for :! says
a pipe '|' in {cmd} is passed to the shell, you cannot use it to append a vim command. See :bar
and :bar says (something that's referred to as escaping it out I think)
'|' can be used to separate commands, so you can give multiple commands in one line. If you want to use '|' in an argument, precede it with '\'.
I tried doing what :bar suggests, i.e.
:! : \| pdflatex -halt-on-error src.tex \| grep '^!.*' -A200 --color=always
The result is it hides everything, including compilation errors that I want to see. So I've come to the conclusion that I have no clue how to properly use shell pipes in vim command mode.
If you aren't a LaTeX user, all that the function is meant to do is the following. pdflatex compiles what's going on in vim into a pdf file. Enacting :! pdflatex % from vim's command mode outputs a whole slew of processing text and interrupts workflow; the grep in the function yanks out compilation errors, if they exist. The function, then, is meant to hide all output from pdflatex unless a compilation error occurs, in which case it outputs only the error and outputs it in red.
If anyone cared to explain the E34 error and why it doesn't work that would be appreciated, also.
Edit 1: This is now solved thanks to filbranden. Below there are a couple pictures attached of a minimal example should anyone come across this later.
vim file before input, output
Edit 2: Should you want to stick this in your .vimrc file, you'll need to escape out the pipe before grep, else the vimrc file defaults to thinking that pipe is a separator.
E34: No previous command
So the answer to your question was hiding in plain sight under :help E34, which redirects to the :! command.
(Vim pro-tip: whenever you get an error from Vim, ask for :help on the error code to get more context about it.)
The section on :! includes this passage:
Any ! in {cmd} is replaced with the previous external command. But not when there is a backslash before the '!', then that backslash is removed.
You did have a ! in your command, as part of the grep regular expression, ^!.*, so that was triggering the "history" behavior, trying to replace with the previously executed command. But since no command had executed at that point, the command failed with an error.
You can solve it by escaping the ! with a backslash, which Vim will remove before passing the command to the shell:
:! pdflatex -halt-on-error src.tex | grep '^\!.*' -A200 --color=always
But note that there are better ways to approach this problem! Let me cover some of them.
Using systemlist()
One great way to run external commands in Vim is to use the systemlist() function, which runs the command on a shell, captures its output, splits it into lines and returns a List with the resulting output lines.
So you could start with:
let latex_output = systemlist('pdflatex -halt-on-error src.tex')
And then use Vimscript commands to check for lines starting with ! to report to the user.
Note that, unlike with :!, the output of systemlist() is never displayed to the user (which means you don't switch back to seeing a terminal, possibly a blank one, and after the execution you don't have a "Hit enter prompt.) Which is great!
But that means you need to present that information to the user, when there are errors. A great way to do that is to use the quickfix window!
You can use the setqflist() function to set the contents of the quickfix window.
(For best results, you should set 'errorformat' appropriately, more on that later.)
Using vim-dispatch
If you don't like the part of running an external command (either through :! or systemlist()) that has it block Vim until the command execution is completed, then consider installing the vim-dispatch plug-in.
It can execute a command for you in background or in a separate terminal, so you're not blocked from editing. It also integrates with the :make command and the quickfix window.
Compiler configuration in vim-latex
Finally, the vim-latex plug-in (also known as latex-suite) has configurations to help you run pdflatex and report errors.
It includes a Vim :compiler configuration that will run pdflatex for you as a :make program. It also will set 'errorformat' to recognize the ! LaTeX Error string and recognize the line number of the errors, so you can jump to them directly from the quickfix list.
Note that vim-latex also has many other features to help you write LaTeX documents in Vim (besides managing the output generation through the compiler support.) You might want to check these other features as well.
(Since the plug-in has quite many features, I recommend reading the whole documentation to get you started on it.)
Also note that this plug-in is compatible with vim-dispatch (since vim-latex provides a compiler interface and vim-dispatch consumes it), so you can use both together if you like them both!

Formatting timestamp in bash for use in a file operation

I'm getting some strangeness from bash when I try to use a timestamp as part of a filename.
#!/bin/bash
DATE=`date -d "today" +"%Y%m%d-%H:%M"`
dtl=$DATE.log
for drive in $( ls /dev/disk/by-id | grep 'scsi-35' ); do
mkdir -p /home/tt/drivelog/${drive}
cp /home/tt/drivelog/currentset/$drive.log "/home/tt/drivelog/$drive/$dtl"
done
The above results in a file named 20171122-12/15.log, so my comma has turned into a forward slash = not what I want.
I tried (to no avail) escaping out the colon by using:
DATE=date -d "today" +"%Y%m%d-%H\:%M"
which results in a file named 20171122-12\/15.log
I use double quotes to ensure there was no ambiguity in the reference, which can happen with colons in filenames. Didn't fix.
When I try some debugging and just echo the source and destination portions of the cp command, it looks right. But that normality disappears when I join them together in the cp command. Echo output:
/home/tt/drivelog/currentset/scsi-35000c50094vv123z.log
/home/tt/drivelog/scsi-35000c50094vv123z/20171122-11:55.log
Lastly, substituting .../${drive}/${dtl}" doesn't fix it...
Many thanks! (Image below, showing recent results)
for John1024:
I made sure date was working, output from date cmd:
20171122-12:47
and as reported in bash:
+ dtl=20171122-12:50.log
Using bash to run the script highlighted the issue:
1. The command is working properly...
+ cp /home/tt/drivelog/currentset/scsi-35000c50094aa123z.log /home/tt/drivelog/scsi-35000c50094aa123z/20171122-12:50.log
The issue is that the Mac on which I am looking at the folder is not showing the output properly.
ls in the output directory shows:
20171122-11:58.log
20171122-12\:00.log
20171122-12\:27.log
20171122-12\:48.log
20171122-12:50.log
Yet the view of this from my Mac drops the colon
I'm going to mark this as closed, as the underlying issue is a Mac AFP display incongruity issue, and not a bash issue. See: here Mac OS used colons as path separators when I first started using them in 1984. With the move to OS X, now eons ago, that changed. AFP and third-party implementations of AFP come with "YMMV" caveats, and this is apparently one I missed.
Many thanks to John1024
The issue here is that the underlying colon is not showing properly over AFP.
The code above does, actually, generate colons as intended. See here for more on the idiosyncrasies of OS X (and prior versions).

Edit conf file in Ubuntu through one line command

I want to change my default web root folder of apache2 web server, but through command line from a script I am making.
I know to do it through nano/vim and then go to the line and change it manually, but I want to make it by a command line.
I though about some thing like (the syntax is wrong - I know - just to make my point):
vim /etc/apache2/sites-enabled/000-default.conf | find 'DocumentRoot /var/www' | replace 'DocumentRoot /var/www/myFolder'
maybe not with vim but other ??
Any Idea ?
Thanks
Use sed with argument -i.
sed -i 's-/var/www-&/MyFolder-' /etc/apache2/sites-enabled/000-default.conf
Argument -i enables in-place editing.
You should use sed with the substitute command for that kind of operation.
http://www.grymoire.com/Unix/Sed.html#uh-0
I don't have a unix machine at hand but something like that should work (using # rather than the usual / as separator):
sed 's#/var/www#/var/www/MyFolder#' /etc/apache2/sites-enabled/000-default.conf
Even if it is not your question, since your initial question mentioned Vim, you can also use substitute from inside Vim
Like
:%s #/var/war#/var/www/MyFolder#g
% means search in the whole file
g means globally : it will replace multiple instance if the string is found multiple times

Simple shell script doesn't work like command line?

I'm trying to write a script that contains this
screen -S demo -d -m which should start a new screen session named demo and detach it.
Putting screen -S demo -d -m in the command line works.
If I put it in a file named boot.sh, and run it ./boot.sh I get
Error: Unknown option m
Why does this work in the command line but not as a shell script?
This file was transferred from windows and had ctrl-M characters.
Running "screen" on my Linux machine, a bad option (Screen version 4.00.03jw4 (FAU) 2-May-06) gives the error,
Error: Unknown option -z"
while your description includes no dash before the offending option. I'd check that the characters in your script file are what you expect them to be. There are many characters that look like a dash but which are not.
cat -v boot.sh
may show something interesting as it'll show codes for non-ascii characters.
This may seem a little like the "make sure your printer is plugged in" kind of help, but anyway:
have you tried to check if the screen you're invoking from the script is the same as the one invoked from the command line ?
I'm thinking you may change the PATH variable inside your script somewhere and perhaps screen from the script would be something else (a different version, perhaps ?).

Why doesn't a * in my pipe open in Perl work on Windows?

I am having this strange issue with Perl. I am trying to execute an external program from inside my Perl script and this external program takes string + wildcard as parameters. My Perl program looks like this
my $cmd_to_run = 'find-something-in-somedb myname* |'
open(procHandle, $cmd_to_run); # I am using open because I want to
# parse the output using pipes
For some weird reason, running this Perl script (under Windows) call to open function ends up with error:
'sqlselect' is not recognized as an internal or external command
I guessed that its something to do with * present in my command string and hence I removed it and now my command string looks like this
my $cmd_to_run = 'find-something-in-somedb myname|'
Now when I run my Perl script it works perfectly fine. Problem comes only when wildcard character is present.
Some points to note :
I ran the same command with wildcard char, in the same cmd prompt (where i am executing this perl script) and it works perfectly fine..
Same command works when I program it in C using _open function in Windows.
Problem seems to be only when wildcard * is present , at least that's what I am guessing
No, I haven't tried this in Unix..
Any clues???
EDIT : I found that this is something to do with ENV . The program that i am trying to run uses "sqlselect" only when "*" wild card is present in search string...
Both find-something-in-somedb and sqlselect are present in same location. In which case how perl is able to find "find-in-db" and not "sqlselect"
Sorry i realize that original problem is turning out to be something else now.. Something to do with "ENV" and not with Wildcard *
It is recommended to use the 3-argument form of open
open(procHandle, '-|', 'find-something-in-somedb', 'myname*');
as that bypasses the shell (which will perform * expansion).
However, on Windows, applications often perform their own quote-parsing and * expansion, so you may need
open(procHandle, '-|', 'find-something-in-somedb', '"myname*"');
or even
open(procHandle, '-|', 'find-something-in-somedb "myname*"');
as I'm not sure exactly how and when Perl hands things off to cmd.
It's very likely that Perl is expanding the wildcard itself, which you don't want to do. The answer provided by ephemient is very good, but in order to debug this, try calling this really simple program:
print join ' ', #ARGV;
Put that into its own file, then call it from your original program (I named mine argv.pl):
my $cmd_to_run = './argv.pl myname* |'
open(procHandle, $cmd_to_run);
That will definitively tell you on your platform how Perl is parsing things. On Unix, the * is expanded to match the files in the current working directory. Not sure about Windows though.
What happens if you use three-argument open?
open my $procHandle, '-|', 'find-something-in-somedb myname*'
or die "Cannot open pipe: $!";

Resources