How do I make wget properly quiet? - windows

wget always echoes system values to the console, even when I specify -q (quiet) on the command line, e.g.:
C:\> wget -q http://www.google.com/
SYSTEM_WGETRC = c:/progra~1/wget/etc/wgetrc
syswgetrc = C:\Program Files\GnuWin32/etc/wgetrc
C:\>
How do I make the noise stop?

that should work:
%> wget.exe parameters_here 1> NUL 2> NUL

Try adding a >NUL:
wget -q http://www.google.com/ >NUL

The more I rely on wget the more annoying these messages get. Appears to be a bug in wget version 1.11.4 (details here), a 2008 vintage that is still the "latest" binary for Windows. I prefer this work-around:
wget ...parameters... 2>>wgeterr.log
#akira 2>NUL makes the two lines go away, but I'm concerned what other error messages it may suppress. The following do not work: >NUL (output is to stderr) nor -q, nor -nv.

Related

How to avoid changing my bash command use in all my scipts

So i have a bash command that has the following options
-v -o -T -S -I -e -t
-t has been changed to -x and -T and -e are no longer availabe.
How can i avoid changing all scripts that use this command with these options that are no longer available or have changed?
You can create a wrapper for your bash command and put it in the PATH before the other executable that is changing.
For instance:
Imaging that the changing bash command is in the /c directory and this is your PATH:
PATH=/a:/b:/c
One approach is to put the wrapper with the same name in the /a (or /b) directory - that is, in the PATH before /c. So, let's say your old script is called old and it's in the /c directory. You can create an old script in the /a directory, and have it call the other script:
COMMAND="/c/old $( sed -e "s:-x::g" -e "s:-T::g" <<< "$#" )"
$COMMAND
So the idea is to manipulate the command arguments before calling the /c/old script. This will need a bit of adjusting if the parameters are more complicated (like they can take a value). There is also likely a quoting issue, it is unlikely that quotes will survive this approach.
If you need to get more complicated, you may consider getopts as a way of parsing the parameters better in the /a/old script.
To be honest, I'm not so happy with this answer - it will not work in a general case. But you asked :) ...

Why does redirecting into file behave differently on windows?

There is a ton of questions relating windows-redirecting, but I can't find anything on this (trivial?) behaviour.
I want to redirect some git-for-windows output into a file. Redirections like these work:
$ dir > test.txt
$ dir test > test.txt
$ ipconfig /all > t
est.txt
But this one outputs to the terminal and creates an empty file:
$ java -version > test.txt
This one outputs to a file correctly, but not if I invoke it from my IDE (which is IAR):
$ git --version > test.txt
The latest case is the one most interesting for me. How do I get the output of any executed program redirected into a file?
Try this way:
git --version > test.txt 2>&1
origin

pipe is returning empty string in bash in git for windows

Edit: Issue has been resolved after update to Git for Windows >= 2.9.0.windows1
Disclaimer
Some comments are referring to full "story" behind this issue but I decided to shorten it because it was getting too long and hard to follow. I present you as succinct failing example as possible. For those who are interested in knowing full context of the problem: it is available in previous revision of the question.
This: basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") is the first (excluding hashbang) line in scripts generated by npm after installing any package which comes with CLI.
For some reason basedir is incorrectly resolved and that's why node can't find module and crashes. I managed to narrow down problem to the pipe in subshell on latest Git for Windows' git-bash. Executing:
echo -n "1:"
echo "a" | cat
echo -n "2:"
echo "$(echo "a" | cat)"
echo -n "3:"
echo "$(echo "a")"
prints:
1:a
2:
3:a
I can't find other people with this issue so I think that it's something wrong with my env (Windows 10 Pro, Git for Windows 2.8.4) and personally I'm out of ideas where it might come from.
My findings:
downgrading Git for Windows to 2.6.4 fixes the problem. Still I don't like being stuck on old version ;/
it works fine on clean Windows 10 VM
pipe output seems to be completely empty because running following snippet doesn't return any result.
On clean installation of mingw + msys problem doesn't occur
snippet:
echo $(echo foobar | cat > bazzzzzzzzzz ; ) ; cat bazzzzzzzzzz
find /c -name bazzzzzzz* 2> /dev/null # /c, /d and /x are my Windows partitions
find /d -name bazzzzzzz* 2> /dev/null # I did test if it actually works for existing file and it does
find /x -name bazzzzzzz* 2> /dev/null
Thanks to agc for invaluable help on figuring this out to this point.
My PATH variable looks like this:
PATH=/c/Users/ja/bin:/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/mingw64/bin:/usr/bin:/c/Users/ja/bin:/c/Windows:/c/Windows/System32:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0:/c/Program Files/nodejs:/c/ProgramData/Oracle/Java/javapath:/c/program files/graphicsmagick-1.3.23-q16:/c/ProgramData/chocolatey/lib/getopt/binaries:/c/Program Files (x86)/Windows Kits/8.1/Windows Performance Toolkit:/c/Program Files/nodejs:/c/Program Files (x86)/Microsoft VS Code/bin:/c/Users/ja/AppData/Roaming/npm:/c/Program Files (x86)/MacType:/usr/bin/vendor_perl:/usr/bin/core_perl
also
$ which sed
/usr/bin/sed
$ which echo
/usr/bin/echo
$ which cat
/usr/bin/cat
$ echo $SHELL
/usr/bin/bash
Summarizing the comments, the short (tl;dr) version: either downgrade, upgrade, and/or re-install MSYS and MinGW that come with Git for Windows.
MSYS supplements MinGW, and the version provided by Git for Windows may be modified from the original maintainers of MSYS. There was a bug reported against MSYS for what appears to be this same issue (using "mingw version: 64 bit bundled with git version 2.8.3.windows.1"), but was marked as "works for me" (i.e., "can't reproduce"). But there was a comment that the problem could be in the repackaging:
"Please be advised that MSYS, as bundled with git for windows, may be modified from our official distribution, (and 64-bit MinGW certainly isn't ours); thus we don't formally support either of these." https://sourceforge.net/p/mingw/bugs/2303/
Long story short, looks like a bug.
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
This seems like an example of the XY problem. Let us break down this line:
echo "$0"
This is usually the path to the script, for example ./alfa.sh
sed -e 's,\\,/,g'
This replaces backslashes with forward slashes. This is where this line starts
to fall apart:
You dont need the -e, you can just do sed 's,\\,/,g'
You probably dont need the g, usually just going to be one slash as shown
above
Changing the slashes doesnt really make sense. Bash, even on Windows, is
going to be using forward slashes already
If for some reason the slashes do need to be changed, Sed is not the right
tool for this anyway, cygpath is:
$ cygpath -m 'C:\Program Files\Mozilla Firefox\firefox.exe'
C:/Program Files/Mozilla Firefox/firefox.exe
dirname
Now you are calling dirname after sed/cygpath. It should be called before, that
way sed/cygpath dont have to replace as much:
basedir=$(cygpath -m "$(dirname "$0")")
Finally, the sed command is bad for another reason; if you are going to be
spitting out a path, it should be an absolute one, because why not?
basedir=$(cygpath -am "$(dirname "$0")")
Notice now that no pipe is even involved. I will also add that this problem was
introduced recently to the NPM repo. You might comment to the devs there.

How to run a series of vim commands from command prompt

I have four text files A.txt, B.txt, C.txt and D.txt
I have to perform a series of vim editing in all these files.
Currently how I am doing is open each files and do the same vim commands one by one.
Is it possible to make a script file which I can run from the command prompt, means without open the actual file for vim editing.
for example, if I have to perform the below vim commands after opening the A.txt file in vim editor:
:g/^\s*$/d
:%s/^/[/
:%s/\(.*\)\(\s\+\)\(.*\)/\3\2\1
:%s/$/]/
:%s/design/test/
Is it possible to make a script file and put all these commands including gvim A.txt (first command in the file).
and edit run the script file from command prompt.
If it is possible, please let me know how to do it and how it can be done with single or multiple files at a time?
vim -c <command> Execute <command> after loading the first file
Does what you describe, but you'll have to do it one file at a time.
So, in a windows shell...
for %a in (A,B,C,D) do vim -c ":g/^\s*$/d" -c "<another command>" %a.txt
POSIX shells are similar, but I don't have a machine in front of me at the moment.
I imagine you could load all the files at once and do it, but it would require repeating the commands on the vim command line for each file, similar to
vim -c "<command>" -c "<command>" -c ":n" (repeat the previous -c commands for each file.) <filenames go here>
EDIT: June 08 2014:
Just an FYI, I discovered this a few minutes ago.
vim has the command bufdo to do things to each buffer (file) loaded in the editor. Look at the docs for the bufdo command. In vim, :help bufdo
The amount of -c commands directly passed to Vim on the command-line is limited to 10, and this is not very readable. Alternatively, you can put the commands into a separate script and pass that to Vim. Here's how:
Silent Batch Mode
For very simple text processing (i.e. using Vim like an enhanced 'sed' or 'awk', maybe just benefitting from the enhanced regular expressions in a :substitute command), use Ex-mode.
REM Windows
call vim -N -u NONE -n -es -S "commands.ex" "filespec"
Note: silent batch mode (:help -s-ex) messes up the Windows console, so you may have to do a cls to clean up after the Vim run.
# Unix
vim -T dumb --noplugin -n -es -S "commands.ex" "filespec"
Attention: Vim will hang waiting for input if the "commands.ex" file doesn't exist; better check beforehand for its existence! Alternatively, Vim can read the commands from stdin. You can also fill a new buffer with text read from stdin, and read commands from stderr if you use the - argument.
Full Automation
For more advanced processing involving multiple windows, and real automation of Vim (where you might interact with the user or leave Vim running to let the user take over), use:
vim -N -u NONE -n -c "set nomore" -S "commands.vim" "filespec"
Here's a summary of the used arguments:
-T dumb Avoids errors in case the terminal detection goes wrong.
-N -u NONE Do not load vimrc and plugins, alternatively:
--noplugin Do not load plugins.
-n No swapfile.
-es Ex mode + silent batch mode -s-ex
Attention: Must be given in that order!
-S ... Source script.
-c 'set nomore' Suppress the more-prompt when the screen is filled
with messages or output to avoid blocking.
With all the commands you want to run on each file saved in a script, say "script.vim", you can execute that script on one file like this (as others have mentioned):
vim -c "source script.vim" A.txt
Taking this one step further, you can save your file at the end of the script, either by putting a :w command inside the script itself, or passing it from the command-line:
vim -c "source script.vim | w" A.txt
Now, you can run any command in Vim on multiple files, by using the argdo command. So your command turns into:
vim -c "argdo source script.vim | w" A.txt B.txt C.txt D.txt
Finally, if you want to quit Vim after running your script on every file, just add another command to quit:
vim -c "argdo source script.vim | w" -c "qa" A.txt B.txt C.txt D.txt
Try the following syntax:
ex foo.txt <<-EOF
g/^\s*$/d
%s/^/[/
%s/\(.*\)\(\s\+\)\(.*\)/\3\2\1
%s/$/]/
%s/design/test/
wq " Update changes and quit.
EOF
The ex command is equivalent to vim -E. Add -V1 for verbose output.
Alternative one-liner syntax is for example:
ex +"g/^\s*$/d" +"%s/^/[/" +"%s/design/test/" -cwq foo.txt
To load commands from the file, use -s cmds.vim.
You can also use shebang for Vim to parse the file from the argument.
For more examples, see:
How to edit files non-interactively (e.g. in pipeline)?
BashFAQ/021
JimR and Ingo have provided excellent answers for your use case.
Just to add one more way to do it, however, you could use my vimrunner plugin to script the interaction in ruby: https://github.com/AndrewRadev/vimrunner.
Example:
vim = Vimrunner.start
vim.edit "file.txt"
vim.insert "Hello"
vim.write
vim.kill
This can be useful for more complicated interactions, since you get the full power of a programming language.
Use vim -s ... to script not only colon commands, but also normal-mode commands such as = for formatting:
Create a file with all keystrokes that you want vim to execute.
Run vim -s SCRIPT-FILE FILE-TO-EDIT
For example: Let's say you want to use vim's = command to re-indent all the lines of myfile.html. First, using vim itself, make a file named myscript that has this:
gg=G:wq
(gg moves to the top of the file; =G re-indents from the current location to the end of the file; :wq<Enter> saves the file and exits.)
Then, run this to have vim launch, edit myfile.html, and save it:
vim -s myscript myfile.html

Shell/Bash - pipe output into another script's input via a variable

Normally I would break things into separate actions and copy and paste the output into another input:
$ which git
/usr/local/bin/git
$ sudo mv git-credential-osxkeychain /usr/local/bin/git
Any quick hack to get output into input?
something like:
$echo which wget | sudo mv git-credential-osxkeychain
set -vx
myGit=$(which git)
gitDir=${myGit#/git} ; gitDir=${gitDir#/bin}/git
echo sudo mv git-credential-osxkeychain ${gitDir}
Remove the set -vx and the echo on the last line when you're sure this performs the action that you require.
It's probably possible to reduce the number of keystrokes required, but I think this version is easier to understand what techniques are being used, and how they work.
IHTH
use command substitution with $(command)
sudo mv git-credential-osxkeychain $(which git)
This substitutes the command for its output. You can find all about it in http://tldp.org/LDP/abs/html/commandsub.html
The answer would be what Chirlo and shellter said.
Why $echo which wget | sudo mv git-credential-osxkeychain wouldn't work is because piping redirect the stdout from a previous command to the stdin of the next command. In this case, move doesn't take input from stdin.
A curious thing is that which git returns
/usr/local/bin/git
but you are moving git-credential-osxkeychain to
/usr/local/git/bin/
Those two don't match. Is there a typo or something?
If you want to use the pipe syntax, then you should look at xargs.

Resources