My goal is to setup doskey to imitate unix touch command as touch filename.txt
Without doskey I use echo . > filename.txt in the windows's command prompt
I successfully setup doskey touch=echo $* but I must use it as touch > filename.txt, I have tried to play around using doskey touch=echo > $*, this causes echo to be not recognized by the windows's command prompt.
Please help, thanks.
Please help,
Try this
doskey touch=copy nul $* > nul
This bit of code exploits the copy command to make a new file. $* is the string you put after touch.
Related
If I try to use Visual Studio Code (on macOS 10.15) to edit my crontab, it opens an empty file without the contents of my crontab.
$ VISUAL='code' crontab -e
crontab: no changes made to crontab
I didn't actually expect this to work (without -w) but include it for completeness. But when I add the -w it still fails.
$ VISUAL="code -w" crontab -e
crontab: code -w: No such file or directory
crontab: "code -w" exited with status 1
It occurred to me that there may be some weirdness with quoting, but neither single quotes nor the following fixed anything:
$ function codew() {
function> code -w "$1"
function> }
$ export VISUAL='codew'
$ crontab -e
The problem seems to be that the crontab's tempfile is not actually present. But how do I solve this? How can I use VS Code to edit crontabs?
Create a file touch ~/code-wait.sh:
#!/bin/bash
OPTS=""
if [[ "$1" == /tmp/* ]]; then
OPTS="-w"
fi
/usr/local/bin/code ${OPTS:-} -a "$#"
Make this file executable:
chmod 755 ~/code-wait.sh
Add to your .bashrc or .bash_profile or .zshrc:
export VISUAL=~/code-wait.sh
export EDITOR=~/code-wait.sh
Run command:
EDITOR='code' crontab -e
here the setting works for me.
.bashrc
## vscode
export VISUAL=/path/to/code-wait.sh
export EDITOR=/path/to/code-wait.sh
code-wait.sh
#!/bin/sh
code -w $*
That is quite a complex issue because there is no way to detect which tool calls the preferred editor. The TTY is the same and no environment variables can help.
Still, I was able to come up with a solution that enables the foreground mode (wait) for temporary files. IMHO, most if not all tools that use external editors and are waiting for them to save the file do use temporary files.
Full script is at https://github.com/ssbarnea/harem/blob/master/bin/edit but I will include here the main snippet:
#!/bin/bash
OPTS=""
if [[ "$1" == /tmp/* ]]; then
OPTS="-w"
fi
/usr/local/bin/code ${OPTS:-} -a "$#"
I have a folder full of jpg files which all end with "-x-large.jpg" I would like to rename them all using command line so that it gets rid of the -x-large and just becomes .jpg.
So for example 123-x-large.jpg will become 123.jpg
Can someone tell me how I can do this with the ren command?
Thanks.
for img in *-x-large.jpg; do mv -i -v "$img" "${img%-x-large.jpg}.jpg"; done
This loops on all matching images and moves them into a new file with a truncated name (removing -x-large.jpg from the end) with the .jpg added back to the end of the file name. I'm invoking this interactively with mv -i so you are prompted before overwriting each file. To force overwriting (always say "yes"), change that to mv (remove the -i). To prevent overwriting (always say "no"), change that to mv -n.
Remove the -v (verbose) if you don't want to see each rename happen.
If you have a very large number of these files, the command line will be too long for the above command (since *-x-large.jpg will be expanded onto a command line). You can work around that with find and xargs as follows:
sh <(find . -maxdepth 1 -name '*-x-large.jpg' \
|sed -r 's/(.*)(-x-large.jpg)$/mv -i "\1\2" "\1.jpg"/')
This creates a shell script using bash process substitution, using find to generate a list of all files we want to rename and then piping them through sed to create the mv commands.
(See above for the mv flags. I removed -v because presumably this will be a very long list.)
See the version below if you want to check the script before running it.
The above one-liner requires GNU bash or Korn shell (ksh) as well as GNU sed.
Here's how to do it with neither (in three commands):
find . -maxdepth 1 -name '*-x-large.jpg' \
|sed 's/.*/mv "&" "&/; s/-x-large.jpg$/.jpg"/' > temp.sh
sh temp.sh
rm temp.sh
Posix sed doesn't reliably support capture groups (\(…\) or sed -r to invoke ERE) and therefore we can't expect it to be able to match and recall text, so this version simply writes most of the command and then fixes the ending (the absence of a trailing double quotes in the first replacement is intentional; we add it in the second replacement). Posix shell (/bin/sh proper) doesn't support process substitution, so we dump to a temporary file, evaluate it, and then remove it.
If we're referring to Windows command-line, then SET /? is your friend. Loads of good info in there.
setlocal ENABLEDELAYEDEXPANSION
set SEARCH_SUFFIX=-x-large.jpg
set REPLACE_SUFFIX=.jpg
for %%A in ("*%SEARCH_SUFFIX%") do (
set OLD_NAME=%%~nxA
set NEW_NAME=!OLD_NAME:%SEARCH_SUFFIX%=%REPLACE_SUFFIX%!
ren "!OLD_NAME!" "!NEW_NAME!"
)
endlocal
My use case: having a repl executable scala.bat which takes some arguments, one of which allows pointing it to a configuration file which is ran on start. I renamed scala.bat to scala-original.bat and called scala-original.bat from inside scala.bat:
#echo off
scala-original.bat -i C:\Progra~2\scala\bin\test-config.scala
How can I pass the original arguments scala.bat was called with to scala-original.bat? They should be added at the end of:
scala-original.bat -i C:\Progra~2\scala\bin\test-config.scala
For example, calling:
scala.bat -nc
should run:
scala-original.bat -i C:\Progra~2\scala\bin\test-config.scala -nc
We can ignore double specifying the -i part again for now.
For my use case, using an alias could also be a solution as seen in https://stackoverflow.com/a/21040825/750216 , eg.:
#echo off
doskey scala=scala-original.bat -i C:\Progra~2\scala\bin\test-config.scala $*
%* is "all parameters to me (the currently running batchfile)". (Try echo %* in a batchfile). That makes it very easy to pass them to the next batchfile:
scala-original.bat -i C:\Progra~2\scala\bin\test-config.scala %*
I inherited a long bash script that I recently needed to modify. The bash script is run as a cronjob on a daily basis. I am decent with bash scripting, but I do not know much about Perl.
I had to substitute all "rm" commands with a call to a perl script that does something similar (for security purposes). This script was not written by me, so there is no -f flag to skip the confirmation prompt. Therefore, to automate this script I pipe "yes" to the script.
Here is an example where I am sequentially deleting two directories:
echo REMOVING FILES TO SAVE DISK SPACE
echo "yes | sudo nice -n -10 perl <path_to_delete_script.pl> -dir <del_dir1>"
yes | sudo nice -n -10 perl <path_to_delete_script.pl> -dir <del_dir1>
echo "yes | sudo nice -n -10 perl <path_to_delete_script.pl> -dir <del_dir2>"
yes | sudo nice -n -10 perl <path_to_delete_script.pl> -dir <del_dir2>
echo DONE.
In my output file, I see the following:
REMOVING FILES TO SAVE DISK SPACE
yes | sudo nice -n -10 perl <path_to_delete_script.pl> -dir <del_dir1>
yes | sudo nice -n -10 perl <path_to_delete_script.pl> -dir <del_dir2>
DONE.
It does not appear that the perl script has run. Yet when I copy and paste those two commands into the terminal, they both run fine.
Any help is appreciated. Thank you in advance.
You simply put do
yes | ./myscript.pl
Thanks for all the comments. I ended up changing the group and permissions of the tool and all output files. This allowed me to run the perl script without using "sudo," which others pointed out is bad practice.
I'm making a script (Perl or shell) that launches a second Perl script. The script that it's launching has thousands of lines of output. So basically I want to make a script that launches another script without any output - and if possible run it within a screen session and then exit the script (yet keep the other running in the screen)? How can I do this?
When you launch your script direct output to /dev/null. To make a script run in the background use the & symbol. For example the follow will show nothing in the console and run in the background...
echo hi > /dev/null &
If you want to run in screen, you have to create a screenrc
#!/bin/sh
echo "screen my_perl_program" > /tmp/$$.screenrc
echo "autodetach on" >> /tmp/$$.screenrc
echo "startup_message off" >> /tmp/$$.screenrc
screen -L -dm -S session1 -c /tmp/$$.screenrc
Then you can restore it with screen -S session1