Miscellaneous operating system functions#
- sage.misc.sage_ostools.have_program(program, path=None)[source]#
Return
True
if aprogram
executable is found in the path given bypath
.INPUT:
program
– a string, the name of the program to check.path
– string or None. Paths to search forprogram
, separated byos.pathsep
. IfNone
, use thePATH
environment variable.
OUTPUT: bool
EXAMPLES:
sage: from sage.misc.sage_ostools import have_program sage: have_program('ls') True sage: have_program('there_is_not_a_program_with_this_name') False sage: have_program('sh', '/bin') True sage: have_program('sage', '/there_is_not_a_path_with_this_name') False sage: have_program('there_is_not_a_program_with_this_name', "/bin") False
>>> from sage.all import * >>> from sage.misc.sage_ostools import have_program >>> have_program('ls') True >>> have_program('there_is_not_a_program_with_this_name') False >>> have_program('sh', '/bin') True >>> have_program('sage', '/there_is_not_a_path_with_this_name') False >>> have_program('there_is_not_a_program_with_this_name', "/bin") False
- class sage.misc.sage_ostools.redirection[source]#
Bases:
object
Context to implement redirection of files, analogous to the
>file
or1>&2
syntax in POSIX shells.Unlike the
redirect_stdout
andredirect_stderr
contexts in the Python 3.4 standard library, this acts on the OS level, not on the Python level. This implies that it only works for true files, not duck-type file objects such asStringIO
.INPUT:
source
– the file to be redirecteddest
– where the source file should be redirected toclose
– (boolean, default:True
) whether to close the destination file upon exiting the context. This is only supported ifdest
is a Python file.
The
source
anddest
arguments can be either Python files or file descriptors.EXAMPLES:
sage: from sage.misc.sage_ostools import redirection sage: fn = tmp_filename()
>>> from sage.all import * >>> from sage.misc.sage_ostools import redirection >>> fn = tmp_filename()
sage: with redirection(sys.stdout, open(fn, 'w')): ....: print("hello world!") sage: with open(fn) as f: ....: _ = sys.stdout.write(f.read()) hello world!
>>> from sage.all import * >>> with redirection(sys.stdout, open(fn, 'w')): ... print("hello world!") >>> with open(fn) as f: ... _ = sys.stdout.write(f.read()) hello world!
We can do the same using a file descriptor as source:
sage: fd = sys.stdout.fileno() sage: with redirection(fd, open(fn, 'wb')): ....: _ = os.write(fd, b"hello world!\n") sage: with open(fn) as f: ....: _ = sys.stdout.write(f.read()) hello world!
>>> from sage.all import * >>> fd = sys.stdout.fileno() >>> with redirection(fd, open(fn, 'wb')): ... _ = os.write(fd, b"hello world!\n") >>> with open(fn) as f: ... _ = sys.stdout.write(f.read()) hello world!
The converse also works:
sage: with open(fn, 'w') as f: ....: _ = f.write("This goes to the file\n") ....: with redirection(f, sys.stdout, close=False): ....: _ = f.write("This goes to stdout\n") ....: _ = f.write("This goes to the file again\n") This goes to stdout sage: with open(fn) as f: ....: _ = sys.stdout.write(f.read()) This goes to the file This goes to the file again
>>> from sage.all import * >>> with open(fn, 'w') as f: ... _ = f.write("This goes to the file\n") ... with redirection(f, sys.stdout, close=False): ... _ = f.write("This goes to stdout\n") ... _ = f.write("This goes to the file again\n") This goes to stdout >>> with open(fn) as f: ... _ = sys.stdout.write(f.read()) This goes to the file This goes to the file again
The same
redirection
instance can be reused multiple times, provided thatclose=False
:sage: f = open(fn, 'w+') sage: r = redirection(sys.stdout, f, close=False) sage: with r: ....: print("Line 1") sage: with r: ....: print("Line 2") sage: with f: ....: _ = f.seek(0) ....: _ = sys.stdout.write(f.read()) Line 1 Line 2
>>> from sage.all import * >>> f = open(fn, 'w+') >>> r = redirection(sys.stdout, f, close=False) >>> with r: ... print("Line 1") >>> with r: ... print("Line 2") >>> with f: ... _ = f.seek(Integer(0)) ... _ = sys.stdout.write(f.read()) Line 1 Line 2
The redirection also works for subprocesses:
sage: import subprocess sage: with redirection(sys.stdout, open(fn, 'w')): ....: _ = subprocess.call(["echo", "hello world"]) sage: with open(fn) as f: ....: _ = sys.stdout.write(f.read()) hello world
>>> from sage.all import * >>> import subprocess >>> with redirection(sys.stdout, open(fn, 'w')): ... _ = subprocess.call(["echo", "hello world"]) >>> with open(fn) as f: ... _ = sys.stdout.write(f.read()) hello world
- sage.misc.sage_ostools.restore_cwd(chdir=None)[source]#
Context manager that restores the original working directory upon exiting.
INPUT:
chdir
– optionally change directories to the given directory upon entering the context manager
EXAMPLES:
sage: from sage.misc.sage_ostools import restore_cwd sage: import tempfile sage: orig_cwd = os.getcwd() sage: with tempfile.TemporaryDirectory() as d: ....: with restore_cwd(d): ....: print(os.getcwd() == orig_cwd) False sage: os.getcwd() == orig_cwd True
>>> from sage.all import * >>> from sage.misc.sage_ostools import restore_cwd >>> import tempfile >>> orig_cwd = os.getcwd() >>> with tempfile.TemporaryDirectory() as d: ... with restore_cwd(d): ... print(os.getcwd() == orig_cwd) False >>> os.getcwd() == orig_cwd True