diff --git a/README.md b/README.md
index 7f5e73a..e7fc95f 100644
--- a/README.md
+++ b/README.md
@@ -98,6 +98,8 @@ cargo fixture -x sh
 
 This will ready the fixture and then enter a shell, in which you can inspect whether the fixture environment is prepared correctly, interact with it, or even run `cargo test` and interact with the environment post-tests.
 
+Alternatively, the shorthand `cargo fixture --shell` can be used, which is equivalent to `cargo fixture -x "$SHELL"`.
+
 ### Platform support
 
 Async runtime: [Tokio](https://tokio.rs/), [smol](https://docs.rs/smol).
diff --git a/src/cli.rs b/src/cli.rs
index 347e790..a6fb86b 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -1,6 +1,6 @@
 use std::{env, ffi::OsString, process};
 
-use anyhow::Result;
+use anyhow::{bail, Result};
 
 use crate::logger::LogLevel;
 
@@ -15,6 +15,7 @@ def_flags!(
     --fixture [name]      parse_value(fixture_name) r#"Name of the fixture setup test (default: "fixture")"#,
     -A --arg [arg]        append_value_raw(fixture_args) "Pass an argument to the fixture test binary (can be used multiple times)",
     -x --exec [args...]   take_remaining(exec) "Instead of running cargo test [args...], run the specified command and pass it all remaining arguments",
+    --shell               set_flag(shell) "Instead of running cargo test, run $SHELL",
     -L [level]            parse_value(log_level) "Stderr logging level (choices: off, info, debug, trace, default: info)",
     -h --help             help "Print help",
     --version             version "Print version",
@@ -55,6 +56,7 @@ pub struct Cli {
     pub fixture_name: String,
     pub fixture_args: Vec<OsString>,
     pub exec: Vec<OsString>,
+    pub shell: bool,
     pub log_level: LogLevel,
     pub cargo_common_all: Vec<OsString>,
     pub cargo_common_test: Vec<OsString>,
@@ -63,6 +65,14 @@ pub struct Cli {
 }
 
 impl Cli {
+    pub fn check_conflicts(self) -> Result<Self> {
+        if self.shell && !self.exec.is_empty() {
+            bail!("--shell and -x/--exec cannot be used at the same time");
+        }
+
+        Ok(self)
+    }
+
     fn unknown_flag(&mut self, flag: OsString) {
         self.cargo_test_args.push(flag);
     }
@@ -74,6 +84,7 @@ impl Default for Cli {
             fixture_name: "fixture".to_string(),
             fixture_args: vec![],
             exec: vec![],
+            shell: false,
             log_level: LogLevel::default(),
             cargo_common_all: vec![],
             cargo_common_test: vec![],
@@ -86,6 +97,7 @@ impl Default for Cli {
 pub fn parse() -> Result<Cli> {
     Parser::new(FLAGS, CARGO_FLAGS, env::args_os())
         .parse()
+        .and_then(|cli| cli.check_conflicts().map_err(parser::Error::Parsing))
         .map_err(|err| {
             let usage = Parser::usage();
             if err.severity() == 0 {
diff --git a/src/cli/flags.rs b/src/cli/flags.rs
index 0063595..5556ecb 100644
--- a/src/cli/flags.rs
+++ b/src/cli/flags.rs
@@ -91,6 +91,7 @@ macro_rules! def_flags {
     };
 
     // Actions
+    (@action set_flag($field:ident)) => { &|parser| { parser.set_flag(|cli| { &mut cli.$field }) } };
     (@action parse_value($field:ident)) => { &|parser| { parser.parse_value(|cli| { &mut cli.$field }) } };
     (@action append_value_raw($field:ident)) => { &|parser| { parser.append_value_raw(|cli| { &mut cli.$field }) } };
     (@action forward($field:ident)) => { &|parser| { parser.forward(|cli| { &mut cli.$field }) } };
diff --git a/src/cli/parser.rs b/src/cli/parser.rs
index b6300e9..300d00b 100644
--- a/src/cli/parser.rs
+++ b/src/cli/parser.rs
@@ -341,6 +341,11 @@ impl Parser {
 
     // flag parse fns
 
+    pub fn set_flag(&mut self, field: impl Fn(&mut Cli) -> &mut bool) -> ParseResult<()> {
+        *field(&mut self.cli) = true;
+        Ok(())
+    }
+
     pub fn parse_value<T>(&mut self, field: impl Fn(&mut Cli) -> &mut T) -> ParseResult<()>
     where
         T: FromStr,
diff --git a/src/config.rs b/src/config.rs
index 04ed33b..297deec 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -7,7 +7,7 @@ use std::{
 
 mod cargo_meta;
 
-use anyhow::Result;
+use anyhow::{anyhow, Result};
 use log::debug;
 
 use self::cargo_meta::CargoMetadata;
@@ -80,8 +80,13 @@ impl Config {
         extra_test_args: Vec<String>,
         extra_harness_args: Vec<String>,
         replace_exec: Vec<String>,
-    ) -> Command {
-        let mut cmd = if let Some(exec) = self.cli.exec.first() {
+    ) -> Result<Command> {
+        let mut cmd = if self.cli.shell {
+            let sh = env::var_os("SHELL").ok_or_else(|| {
+                anyhow!("The environment variable $SHELL is not set, needed by --shell")
+            })?;
+            Command::new(sh)
+        } else if let Some(exec) = self.cli.exec.first() {
             let mut cmd = Command::new(exec);
             cmd.args(&self.cli.exec[1..]);
             cmd
@@ -106,6 +111,6 @@ impl Config {
 
         cmd.env("CARGO_FIXTURE_SOCKET", &self.socket_path);
 
-        cmd
+        Ok(cmd)
     }
 }
diff --git a/src/server.rs b/src/server.rs
index 62c10cc..9d032b4 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -187,7 +187,7 @@ impl FixtureConnection {
         let replace_exec = mem::take(&mut self.replace_exec);
         let test_cmd = self
             .config
-            .test_cmd(extra_test_args, extra_harness_args, replace_exec);
+            .test_cmd(extra_test_args, extra_harness_args, replace_exec)?;
         info!("running {}", test_cmd.display());
         let status = test_cmd
             .into_smol(Stdio::inherit(), Stdio::inherit(), Stdio::inherit())
diff --git a/tests/args.rs b/tests/args.rs
index ff0808a..f103beb 100644
--- a/tests/args.rs
+++ b/tests/args.rs
@@ -160,3 +160,8 @@ fn args() {
         &["exec-cli-arg1", "exec-cli-arg2"],
     );
 }
+
+#[test]
+fn shell() {
+    cargo_fixture().run_assert_shell();
+}
diff --git a/tests/common/mod.rs b/tests/common/mod.rs
index b08a222..8bf1737 100644
--- a/tests/common/mod.rs
+++ b/tests/common/mod.rs
@@ -161,6 +161,32 @@ impl CargoFixture {
         );
     }
 
+    pub fn run_assert_shell(mut self) {
+        let print_args_exe = self.print_args_exe();
+
+        let report = self
+            .cmd
+            .args([
+                "-L",
+                "debug",
+                "--fixture",
+                "fixture_args",
+                "-A",
+                "report",
+                "--shell",
+            ])
+            .stdin(Stdio::null())
+            .stdout(Stdio::piped())
+            .stderr(Stdio::inherit())
+            .env("SHELL", &print_args_exe)
+            .output()
+            .unwrap()
+            .parse_args_report();
+
+        assert!(report.fixture_args.is_empty(), "{report:?}");
+        assert_eq!(report.test_args, &[print_args_exe.as_str()], "{report:?}");
+    }
+
     pub fn print_args_exe(&mut self) -> String {
         self.print_args_exe
             .get_or_insert_with(|| {