How to put a comment after a IPython magic command - ipython

How can I put a comment at the end of an IPython magic command?
Eg, trying to use %cd:
%cd "dir" # comment
I want to change to directory dir but instead I get:
[Errno 2] No such file or directory: 'dir # comment'

It's not possible in general because IPython magic commands parse their own command lines.*
There are some magic commands where comments seem to work, but actually they're being handled in another way. For example:
%ls # comment works properly, but %ls is an alias to a shell command, so the shell is what's parsing the comment.
%automagic 0 # comment behaves like %automagic, toggling the setting instead of exclusively disabling it like %automagic 0 would do. It's as if the 0 # comment is all one string, which it ignores.
%run $filename # comment treats the comment as arguments, so ['#', 'comment'] ends up in sys.argv for $filename.
Workaround
You could call magic commands using exclusively Python syntax.
First get the running IPython instance with get_ipython():
ipython = get_ipython()
Then:
ipython.run_line_magic('cd', 'dir') # comment
Docs: InteractiveShell.run_line_magic()
Or for cell magics, you could go from this (which doesn't work):
%%script bash # comment
echo hello
to this:
ipython.run_cell_magic('script', 'bash', 'echo hello') # comment
Docs: InteractiveShell.run_cell_magic()
Another option, I suppose, is to run an entire cell, although, suppressing the output since it returns an ExecutionResult object:
ipython.run_cell('%cd dir'); # comment
Docs: InteractiveShell.run_cell()
* I'm not sure if this is documented explicitly, but it is documented implicitly under defining custom magics, and I found the clues in this GitHub issue: Allow comments after arguments in magic_arguments.

TL;DR: You cannot as things stand. This might or might not be an error in the implementation of %cd.
Until this is fixed, one way to avoid this is to use:
import os
os.chdir("dir") #some comment here
A second alternative is using bash commands.
However % is a magic command, not equivalent to a bash command. This is on purpose,
as it can change the current directory of the notebook.
This is not the same as e.g.
!cd dir #some comment here
Which will spawn a shell and execute the command there thus not changing the current directory. (You can verify using pwd before/after each command)
Note that if your goal is not to change the current jupyter notebook directory, you can issue multiple commands in one cell with the magic
%sh:
%%sh
cd dir #some comment here
ls #some more commands here
....
This command will spawn a shell and all bash commands will be executed there, so the current jupyter directory will not change.

Related

In Jupyter Notebooks on Google Colab, what's the difference between using % and ! to run a shell command?

Question is in the title.
I know that % usually denotes a "magic variable" in IPython. That's not a concept I'm terribly familiar with yet, but I have read about it.
However, today I saw a tutorial where someone was using it to run a shell command. Normally I have seen and used !.
Is there a difference? Both seem to be doing the same thing when I try them.
The difference is this:
When you run a command with !, it directly executes a bash command in a subshell.
When you run a command with %, it executes one of the magic commands defined in IPython.
Some of the magic commands defined by IPython deliberately mirror bash commands, but they differ in the implementation details.
For example, running the !cd bash command does not persistently change your directory, because it runs in a temporary subshell. However, running the %cd magic command will persistently change your directory:
!pwd
# /content
!cd sample_data/
!pwd
# /content
%cd sample_data/
!pwd
# /content/sample_data
Read more in IPython: Built-in Magic Commands.

Run command line via alias with zsh on MATLAB

I use the system/unix command on Matlab in order to run an external program via the command line. I want to execute it via an alias define in .zshrc on my computer. Unfortunately, the alias seems to be not available.
Example with ll
on a terminal: which ll gives ll: aliased to ls -lh
on Matlab: unix('ll') gives zsh:1: command not found: ll
I check if I used the right shell: unix('echo $SHELL') gives /usr/local/bin/zsh.
I have add setopt aliases in my .zshrc but it changes nothing. Is it possible to check which startup files is used when you open a non interactive shell?
The ~/.zshrc seems to be not loaded in the non interactive case. The solution consists in loaded aliases and added setopt aliases in ~/.zshenv. See this for instance.

How to create a alias in fish shell

I try to create an alias for ls (should basically just map to ls -lah)
I've tried the following code, but it's not working:
function ls
ls -lah
end
funcsave ls
but when I call it I get this message:
The function 'ls' calls itself immediately, which would result in an infinite loop.
in function 'ls'
called on standard input
What you're looking for is the command command.
I would also recommend to pass any arguments (stored in $argv) to the aliased command.
So your example should be:
function ls
command ls -lah $argv
end
And to do all this with a simple command, you can simply use the alias command.
alias ls "command ls -lah"
Note that usually aliases will not get you the nice auto-complete suggestions that contribute to _fish_'s friendliness. This specific case is an exception because the function and the original command have the same way, but otherwise, here are two ways to get completions anyway:
You can use the complete command to tell fish that your alias uses the same completions as the aliased command.
The balias plugin
serves as an alternative to alias and does just that.
fish also offers an abbr command. It works slightly different and will actually expand the abbreviated command to the full command in the command line, and then fish will have no problem giving you all the auto-completion suggestions that it knows.
You need the command keyword. Also, pass the function's arguments to ls
function ls
command ls -lah $argv
end
If you need to make alias of ls, then the above answers are OK.
However, fish already has a command for ls -lah, which is la.

How can I modify command line in Ubuntu 10.04?

I am using a vpn service from certain server. I was given with a root account, and when I connect with a root account, the command line looks like below.
root#xa9g82:/etc/#
Then I used useradd to add an account called 'temp'
When I connected to the server with temp, then the command line only has a single character.
$
The user information is not shown, neither the path. Also, note that, in root's command line I can use tab to automatically complete the filename, however 'temp's command line inserts tab space, when I press tab. It is very inconvenient.
I am using Ubuntu 10.04. How can I resolve this issue?
I usually edit ~/.bashrc. Being root, you might want to change the system-wide preferences, at /etc/bash.bashrc. Personally, I changed some lines in ~/.bashrc to look like:-
# If this is an xterm set the title to user#host:dir
case "$TERM" in
xterm*|rxvt*)
## PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u#\h: \w\a\]$PS1" # default
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\h: \W\a\]$PS1" # How I like it
;;
*)
;;
esac
use prompt to set the prompt.... (man prompt...)
it depends on what shell you run each one has it's own tricks, but you can make it looks as you wish.
BASH
TCSH
It is likely that the default shell for root is set to /bin/sh, which does not provide many of the features that you may used to if you use a shell like bash. To check if this is the case, run the following command:
cat /etc/passwd | grep ^root
The last component of the line that this command outputs will be your shell (which, as stated previously, I'm guessing is /bin/sh). If this is not the shell you want (it probably isn't), then edit /etc/passwd (using nano or whatever editor you're most comfortable with) and change your shell to something more palatable, like /bin/bash. After doing this, you'll need to log out and then log back in.

Auto-complete command line arguments

In bash, executables such as mplayer and imagemagick's "convert" have a cool auto-complete functionality on their command line arguments. For instance, if I type
mplayer <tab><tab>
in one of my video folders, then mplayer will list all media files located in that folder, and only the media files.
Similarly, if I type
convert -<tab><tab>
then I will see all the possible options of the convert script, which is great.
My question is how to achieve a similar functionality, using bash, ruby or python scripts?
This is an example of BASH's smart completion. A basic description is here, a guide to writing your own extensions is here and another (Debian-based) guide is here. And here's a fuller featured introduction to the complete command (the command that facilitates this behaviour).
The link to writing your own extension in the accepted answer has gone dead. Quoting here from http://web.archive.org/web/20090409201619/http://ifacethoughts.net/2009/04/06/extending-bash-auto-completion/
Bash provides you a way of specifying your keywords, and using them to
auto complete command line arguments for your application. I use vim
as a wiki, task managemer and contacts. The vim helptags system lets
me index the content instead of searching through it, and the speed
shows it. One feature I wanted to add to this was to access these tags
from outside vim.
This can be done in a straight forward way:
$ vim -t tagname
This takes me directly to specific content marked using this tag. However, this will be more productive if I can provide
auto-completion for the tags.
I first defined a Bash function for the vim commandline. I added the
following code to my .bashrc file:
function get {
vim -t $1
} Now I can use get tagname command to get to the content.
Bash programmable completion is done by sourcing the
/etc/bash-completion script. The script lets us add our
auto-completion script /etc/bash-completion.d/ directory and executes
it whenever it is called. So I added a script file called get with the
following code in that directory.
_get()
{
local cur
COMPREPLY=()
#Variable to hold the current word
cur="${COMP_WORDS[COMP_CWORD]}"
#Build a list of our keywords for auto-completion using
#the tags file
local tags=$(for t in `cat /home/anadgouda/wiki/tags | \
awk '{print $1}'`; do echo ${t}; done)
#Generate possible matches and store them in the
#array variable COMPREPLY
COMPREPLY=($(compgen -W "${tags}" $cur))
}
#Assign the auto-completion function _get for our command get.
complete -F _get get Once the /etc/bash-completion is sourced, you will get auto-completion for the tags when you use the get command.
Along with my wiki I use it for all the documentation work and at
times the code too. I also use the tags file created from my code. The
indexing system lets me remember the context instead of the filenames
and directories.
You can tweak this system for any of the tools you use. All you need
to do is get a list of the keywords for your command and give it to
the Bash programmable completion system.
This functionality in bash is provided by bash-completion and similar functionality is included in zsh. If you want to add support for some program not currently supported by one of these tools, you need to write your own extensions for them.
How do I enable bash completion on Ubuntu?
sudo apt-get install bash-completion
source /etc/profile.d/bash_completion.sh
sudo apt i[TAB]