summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fish/fish.c16
-rw-r--r--guestfish.pod13
2 files changed, 29 insertions, 0 deletions
diff --git a/fish/fish.c b/fish/fish.c
index fcafb5ca..a956bf9e 100644
--- a/fish/fish.c
+++ b/fish/fish.c
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
+#include <signal.h>
#include <assert.h>
#ifdef HAVE_LIBREADLINE
@@ -359,6 +360,21 @@ script (int prompt)
/* If the next character is '#' then this is a comment. */
if (*buf == '#') continue;
+ /* If the next character is '!' then pass the whole lot to system(3). */
+ if (*buf == '!') {
+ int r;
+
+ r = system (buf+1);
+ if (!prompt) {
+ if (r == -1 ||
+ (WIFSIGNALED (r) &&
+ (WTERMSIG (r) == SIGINT || WTERMSIG (r) == SIGQUIT)) ||
+ WEXITSTATUS (r) != 0)
+ exit (1);
+ }
+ continue;
+ }
+
/* Get the command (cannot be quoted). */
len = strcspn (buf, " \t");
diff --git a/guestfish.pod b/guestfish.pod
index 746922f8..b464c717 100644
--- a/guestfish.pod
+++ b/guestfish.pod
@@ -189,6 +189,19 @@ but B<not> by a command. For example:
Blank lines are also ignored.
+=head1 RUNNING COMMANDS LOCALLY
+
+Any line which starts with a I<!> character is treated as a command
+sent to the local shell (C</bin/sh> or whatever L<system(3)> uses).
+For example:
+
+ !mkdir local
+ tgz-out /remote local/remote-data.tar.gz
+
+will create a directory C<local> on the host, and then export
+the contents of C</remote> on the mounted filesystem to
+C<local/remote-data.tar.gz>. (See C<tgz-out>).
+
=head1 COMMANDS
=head2 help