=head1 NAME

nbdsh - network block device (NBD) shell

=head1 SYNOPSIS

 $ nbdsh

 Welcome to nbdsh, the shell for interacting with
 Network Block Device (NBD) servers.

 The ‘nbd’ module has already been imported and there
 is an open NBD handle called ‘h’.

 nbd> h.connect_command(["nbdkit", "-s", "memory", "1G"])
 nbd> h.get_size()
 1073741824
 nbd> buf = b"hello, world"
 nbd> h.pwrite(buf, 0)
 nbd> exit()

=head1 DESCRIPTION

nbdsh is a Python-based interactive shell for accessing Network Block
Device (NBD) servers.

For documentation about the libnbd API please open the shell and type:

 help(nbd)

For an introduction to using libnbd from Python see
L<libnbd-python(3)>.

=head1 EXAMPLES

There are other example scripts in the libnbd source repository under
F<sh/examples> or see
L<https://gitlab.com/nbdkit/libnbd/tree/master/sh/examples>.

=head2 Print the size of an NBD export

The I<-u> option connects to an NBD URI.  The I<-c> option lets
you execute single Python statements from the command line.  Combining
these two options lets you print the size in bytes of an NBD export:

 $ nbdsh -u nbd://localhost -c 'print(h.get_size())'
 1073741824

=head2 Hexdump the boot sector of an NBD export

Using I<-c -> you can feed a whole Python program to the standard
input of nbdsh:

__EXAMPLES_HEXDUMP__

L<nbddump(1)> is another tool for hexdumping NBD exports.

=head2 Overwrite part of the disk with a pattern

Overwrite 2048 bytes, starting at offset 1024 (hex 0x400), with the
repeating binary pattern S<01010101 10101010>.  (This operation is
destructive!)

 $ nbdkit memory 4096
 $ nbdsh -u nbd://localhost -c 'h.pwrite(b"\x55\xAA" * 1024, 0x400)'
 $ nbddump nbd://localhost
 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │················│
 ☆
 0400: 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa │U·U·U·U·U·U·U·U·│
 ☆
 0c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │················│
 ☆
 0ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │················│
 $ killall nbdkit

The I<-c> parameter contains a Python expression which builds a
bytearray containing the two byte pattern repeated 1024 times (length
2048 bytes), and calls the Python binding of L<nbd_pwrite(3)>.  The
second parameter is the offset to start writing from.  For information
about nbdkit, see L<nbdkit(1)> and L<nbdkit-memory-plugin(1)>.

=head1 OPTIONS

=over 4

=item B<-h>

=item B<--help>

Display brief command line help and exit.

=item B<--base-allocation>

Request the use of the "base:allocation" meta context, which is the
most common context used with L<nbd_block_status_64(3)>.  This is
equivalent to calling
S<C<h.set_meta_context(nbd.CONTEXT_BASE_ALLOCATION)>> in the shell
prior to connecting, and works even when combined with C<--uri> (while
attempting the same with C<-c> would be too late).

=item B<-c> 'COMMAND ...'

=item B<--command> 'COMMAND ...'

Instead of starting an interactive shell, run a command.  This option
can be specified multiple times in order to run multiple commands.

=item B<-c ->

=item B<--command ->

Read standard input and execute it as a command.

=item B<-n>

Do not create the implicit handle C<h>.

=item B<--opt-mode>

Request that option mode be enabled, which gives fine-grained control
over option negotiation after initially contacting the server but
prior to actually using the export.  This is equivalent to calling
S<C<h.set_opt_mode(True)>> in the shell prior to connecting, and works
even when combined with C<--uri> (while attempting the same with C<-c>
would be too late).

=item B<-u> URI

=item B<--uri> URI

Connect to the given L<NBD URI|https://github.com/NetworkBlockDevice/nbd/blob/master/doc/uri.md>.
This is equivalent to the S<C<h.connect_uri(URI)>> command in the shell.

Note that the connection is created prior to processing any C<-c>
commands, which prevents the use of configuration commands such as
S<C<h.add_meta_context(>NAMEC<)>> from the command line when mixed
with this option.  The options C<--opt-mode> and C<--base-allocation>
can be used to make this situation easier to manage.

=item B<-v>

=item B<--verbose>

Enable verbose libnbd messages.  This has the same effect as setting
the environment variable C<LIBNBD_DEBUG=1>

=item B<-V>

=item B<--version>

Display the package name and version and exit.

=back

=head1 SEE ALSO

L<libnbd(3)>,
L<libnbd-python(3)>,
L<libnbd-security(3)>,
L<nbdcopy(1)>,
L<nbddiscard(1)>,
L<nbddump(1)>,
L<nbdfuse(1)>,
L<nbdinfo(1)>,
L<nbdublk(1)>,
L<nbdzero(1)>,
L<qemu-img(1)>,
L<nbdkit(1)>.

=head1 AUTHORS

Richard W.M. Jones

=head1 COPYRIGHT

Copyright Red Hat
