running ipython in non-interactive mode - ipython

I was hoping it would be easy to rewrite a few bash scripts using ipython by using the "!" command. Unfortunately if I try to run ipython in non-interactive mode like so:
ipython -p sh myipythonscript.py
where myipythonscript.py contains commands like:
env=%env
d=!ls
This doesn't work. I get SyntaxError.
Is there an option which allows ipython to be run in non-interactive mode?

Python also has modules which makes it easy to completely replace bash calls. these are easier to debug and give better error handling.
for example instead of ls you can use glob, it supports the same syntax:
files=glob.glob('myfiles*.txt')
for environment variables:
env = os.environ
for path related functions:
os.path
for common operations, os.mkdir, os.chmod, os.getcwd [same as pwd]

Related

How to switch NVM environments within perl

I am writing a perl script, and I want to run a simple shell command to use a certain version of NVM:
Here is my code snippet:
print "\n*** Switching to correct nvm environment for dashboard builds\n";
system("nvm use 8.12.0") == 0 or die $?;
But I am getting the following error:
Can't exec "nvm": No such file or directory
Can someone help?
Update (June 30, 2021):
I also tried adding the command:
my $nvm_version = "8.12.0";
system ("bash", "-lic", "nvm use $nvm_version");
But nothing happens:
I'm not familiar with nwm, but I think I get the gist of what it does. And if so, the attempt is fundamentally flawed. Even if you fixed this to run the proper shell so that nvm could run, I believe all the tool does is change the shell's environment variables, a shell you immediately exit. This means it would have no effect even if if it ran successfully.
Again, it this tool does what I think it does, such tool are meant to be used in interactive shells. In other instances, you simply use the path the to correct executable instead of relying on the PATH.
With that in mind, you can use the following to run the command in bash:
# Non-interactive shell.
system("bash", "-c", "nvm use 8.12.0")
or
# Interactive shell.
# This is improper and fragile as interactive shells
# often create aliases that override basic commands.
system("bash", "-ic", "nvm use 8.12.0")
Just to reiterate, at least one of these will allow the command to run (if it normally works from bash), but I believe it's unlikely this will produce the results you expect.
The nvm command is shell function which is different from a shell command. Also the nvm command is not an exported function so it will not be seen by sub shells. For example, in Bash shell:
$ nvm ls
-> v15.0.1
$ my-test-script.sh
./my-test-script.sh: line 3: nvm: command not found
where my-test-script.sh is:
#! /bin/bash
nvm use 16.4
The error nvm: command not found is because nvm is not exported. I can source the script in the current shell context to make it work:
$ source my-test-script.sh
Now using node v16.4.0 (npm v7.18.1)
$ node --version
v16.4.0
So a Perl script cannot change the node version of the current shell, but it can calculate the version and pass it back to shell, which can set the version. For example:
$ nvm use $(perl -E'$v=15.0; print $v')
Now using node v15.0.1 (npm v7.0.3)

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.

ipython magic/macro/alias guidance for invoking shell and dispatching result

(Note: I have plenty of python and unix shell experience, but fairly new to ipython -- using 7.5)
I'm trying to replicate a UNIX shell function that I use all the time, so that it works in the ipython shell.
The requirement is that I want to type something like to myproj, and then have ipython process the resulting text by doing a cd to the directory that comes back from to. (This is a quick-directory-change utility I use in unix)
The way it works in unix is that a shell function invokes an external command, that command prints its result to stdout, and the shell function then invokes the internal cd to the target dir.
I've been trying to wrap my head around %magic and macros and aliases in ipython, but so far I don't see how to get this done. Any ideas?

How to pass a device path to an ipython profile startup script?

I'm looking for a way to pass the path of a USB/serial device to my ipython profile startup file on OS X. Because the device file can have an awkward name it would be nice if I could leverage bash completion. Something like:
$ ipython --profile test /dev/tty.usb[TAB]
I could then make this in to an alias `ipython-test /dev/tty.usb[TAB]'.
I'd like to do this to allow my startup script to establish a connection with some hardware.
Other ideas welcome of course.
You can do that by evaluating a bash command there which will give you this autocompletion effect. E.g. with tab you'd like to get the first matching entry, here's a code which will do that for you:
ipython --profile test `ls /dev/tty | head -n1`
For understanding how that works see Understanding backticks in bash.

Executing a python file from IPython

I'm relatively new to NumPy/SciPy and IPython.
To execute a python script in the python interactive mode, we may use the following commands.
>>> import os
>>> os.system('executable.py')
Then the print outputs can be seen from the python prompt.
But the same idea doesn't work with IPython notebook.
In [64]:
import os
os.system('executable.py')
Out[64]:
0
In this case, I cannot see any print outputs. The notebook only tells weather execution was successful or not. Are there any ways to see the outputs when I use IPython notebook?
Use the magic function %run:
%run executable.py
This properly redirects stdout to the browser and you will see the output from the program in the notebook.
It gives you both, the typical features of running from command line plus Python tracebacks if there is exception.
Parameters after the filename are passed as command-line arguments to
the program (put in sys.argv). Then, control returns to IPython's
prompt.
This is similar to running at a system prompt python file args,
but with the advantage of giving you IPython's tracebacks, and of
loading all variables into your interactive namespace for further use
(unless -p is used, see below).
The option -t times your script. With -d it runs in the debugger pdb. More nice options to explore.