How do I create my own custom command line script in zsh? - command-line

I want to be able to run simple one line commands on my terminal, but instead of them being complicated I want them to be very simple, writing my own commands for these complex command lines that I have to write out so frequently. I am using the zsh command line and for example I would want to do this.
% npx tailwindcss -i ./static/styles.css -o ./static/output.css --watch
into something much easier to read such as
% build tailwindcss
Another problem/example is where if I would like to use http-server, but I want to turn off the caching, I don't think you can change the default settings for http-server module to turn off the caching, I have to do this:
% http-server -c-1
I know it is not too much of a big deal but I would like to at least pretend that the zero caching is the default. So I could do something like this with the command line:
% run server
And that would just run the server.
Also as a side note if this is not the best command line tool to do stuff like this in like maybe bash would be better I would be open to using a different command line tool as well.

Using aliases
If you run the exact same command every time you could alias it like this:
alias http-server="http-server -c-1"
alias <alias-name>="npx tailwindcss -i ./static/styles.css -o ./static/output.css --watch"
Now http-server expands to http-server -c-1 and <alias-name> expands to npx tailwindcss -i ./static/styles.css -o ./static/output.css --watch
Using functions
If you want to choose the input file each time you could write a function instead:
build(){
npx tailwindcss -i $1 -o ./static/output.css --watch
}
Then you can build with build file.css
Add the alias or function to ~/.zshrc if you want it available every time you start zsh
Using bck-i-search
Use Ctrl+r to search history. Pressing Ctrl+r and writing "tailwind" will likely show you the full command. You can even comment the function with some arbitrary words to make them easier to find in history (e.g. "aaa")
npx tailwindcss -i ./static/styles.css -o ./static/output.css --watch #aaa

Related

How can I get zsh to inherit the complete autocompletion?

I have an little shell script (named "run") which redirects all output of a program to /dev/null:
#!/bin/bash
$# &> /dev/null &
disown +
How can I say zsh that the whole autocompletion shall work for this?
I mean
$ run git com<TAB>
autocomplete to
$ run git commit
I was able to make that work by adding:
compdef _command run
to my .zshrc file.
I've based my answer on this bash question. It was worth giving it a try with compdef - surprisingly it worked.
As I'm still zsh/autocompletion newbie I cannot explain the inner workings and you should probably go through the documentation or other sources to find more on the topic.

Supervisord- Execute a command before starting the application / program

Using supervisord, how do I execute a command before running the program?
For example in the code below, I want a file to be created before starting the program. In the code below I am using tail -f /dev/null to simulate the background process but this could be any running program like '/path/to/application'.
I tried '&&' and this doesn't seem to work. The requirement is that the file has to be created first in order for the application to work.
[supervisord]
nodaemon=true
logfile=~/supervisord.log
[program:app]
command:touch ~a.c && tail -f /dev/null
The problem is that supervisor isn't running a shell to interpret command sections, so "&&" is just one of 5 space separated arguments it is passing to the touch command; if this ran successfully, then there should be some unusual filenames in its working directory now.
You can use a shell as your command and pass it the shell logic you would like:
command=/bin/sh -c "touch ~a.c && tail -f /dev/null"
Usually, this type of shell wrapper should be the interface provided and managed by the app and is what supervisord and others just know how to call with paths and options, i.e.:
command=myappswrapper.sh ~a.c
(where myappswrapper.sh is:)
#!/bin/sh
touch $1 && tail -f /dev/null
Here is a trick.
You use a shell script to do that and beyond that
[program:app]
command:sh /path/to/your/script.sh
It's can your script.sh
touch ~a.c
exec tail -f /dev/null
notice exec

how to use -o flag in wget with -i?

I understand that -i flag takes a file (which may contain list of URLs) and I know that -o followed by a name can be specified to rename a item being downloaded using wget.
example:
wget -i list_of_urls.txt
wget -o my_custom_name.mp3 http://example.com/some_file.mp3
I have a file that looks like this:
file name: list_of_urls.txt
http://example.com/some_file.mp3
http://example.com/another_file.mp3
http://example.com/yet_another_file.mp3
I want to use wget to download these files with the -i flag but also save each file as 1.mp3, 2.mp3 and so on.
Can this be done?
You can use any script language (PHP or Python) for generate batch file. In thin batch file each line will contains run wget with url and -O options.
Or you can try write cycle in bash script.
I ran a web search again and found https://superuser.com/questions/336669/downloading-multiple-files-and-specifying-output-filenames-with-wget
Wget can't seem to do it but Curl can with -K flag, the file supplied can contain url and output name. See http://curl.haxx.se/docs/manpage.html#-K
If you are willing to use some shell scripting then https://unix.stackexchange.com/questions/61132/how-do-i-use-wget-with-a-list-of-urls-and-their-corresponding-output-files has the answer.

how to retrive a perl file using wget and execute it using a one-liner?

I'm looking to use wget to retrieve a perl file and execute it in one line. Does anyone know if this is possible/how I would go about doing this?
In order to use wget for this purpose, you would use the -O flag and give it the '-' character as an argument. From the manpage:
-O file
--output-document=file
Giving '-' as the "file" option to -O tells it to send it's output to stdout, which can then be piped into the Perl command.
You can provide the -q flag as well to turn off wget's own warning and message output:
-q
--quiet
Turn off Wget's output.
This will make things look cleaner in the shell.
So you would end up with something like:
wget -qO - http://127.0.0.1/myscript.pl | perl -
For more information on I/O redirection take a look at this:
http://www.tldp.org/LDP/abs/html/io-redirection.html
Just download and pipe to perl
curl -L http://your_location.pl | perl -
You'll sometimes see code like for install modules like cpanm.

Bash: rewriting emacs command in bash_profile

I'm trying to write a command in my bash_profile to replace the default emacs command that will emacs a file if it exists, and if it doesn't exist, will copy a template to the new file and then emacs that.
What I attempted was:
function emacs()
{
if [ ! -f ${1} ]; then \
cp /FILEPATH/template.sh ${1}; fi;
builtin emacs ${1}
}
but the error I'm getting is "-bash: builtin: emacs: not a shell builtin"
How do I create a new function to replace the emacs command and then call the original emacs command within that function if emacs is not a builtin command?
You want command emacs, not builtin emacs. See help command.
As an aside, doesn't emacs have some sort of internal support for new-file templates? You might want to take a look at this: http://www.emacswiki.org/emacs/TemplatesMode. (Disclaimer: I don't use emacs; this was just one of the first pages I found while searching for "emacs new file template.)
(edit: sorry, command emacs in the other answer is better, use that.)
builtin only works for actual shell builtins like test, read, ...
Use the explicit path to emacs instead:
function emacs()
{
if [ ! -f ${1} ]; then \
cp /FILEPATH/template.sh ${1}; fi;
/usr/bin/emacs ${1}
}