diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 0dea54788264fe21cc9f335854c16d3c96d82230..05719854b22925a9dcdc2f776a8f6d37f36d60cc 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -117,6 +117,7 @@ std::vector<std::pair<std::string, std::string> > GetUsage()
   s.push_back(mp("-listen",            "Always listen to incoming connection requests"));
   s.push_back(mp("-minterpreter string", "Name of Octave interpreter"));
   s.push_back(mp("-pyinterpreter string", "Name of Python interpreter"));
+  s.push_back(mp("-run",               "Run ONELAB solver(s)"));
   s.push_back(mp("Display options:", ""));
   s.push_back(mp("-n",                 "Hide all meshes and post-processing views on startup"));
   s.push_back(mp("-nodb",              "Disable double buffering"));
@@ -308,6 +309,13 @@ void GetOptions(int argc, char *argv[])
         CTX::instance()->batch = -99;
         i++;
       }
+      else if(!strcmp(argv[i] + 1, "run")) {
+        // same as '-', but will run local Gmsh client (if no other clients are
+        // requested, e.g. by opening a '.pro' or '.py' file)
+        CTX::instance()->batch = -99;
+        CTX::instance()->launchSolverAtStartup = -2;
+        i++;
+      }
       else if(!strcmp(argv[i] + 1, "onelab")) {
         i++;
         if(argv[i] && argv[i + 1] && argv[i + 1][0] != '-'){
diff --git a/Common/gmshLocalNetworkClient.cpp b/Common/gmshLocalNetworkClient.cpp
index 1bf5bd5d060e8cccaf9d27eb3a691b4d1de5d5b7..ef92f8471a629ea715fddf6f8cef86529b5e4d01 100644
--- a/Common/gmshLocalNetworkClient.cpp
+++ b/Common/gmshLocalNetworkClient.cpp
@@ -798,12 +798,27 @@ void resetDb(bool runGmshClient)
 void solver_batch_cb(void *data)
 {
   int num = (intptr_t)data;
-  if(num < 0) return;
-  std::string name = opt_solver_name(num, GMSH_GET, "");
-  std::string exe = opt_solver_executable(num, GMSH_GET, "");
-  std::string host = opt_solver_remote_login(num, GMSH_GET, "");
-  if(exe.empty()){
-    Msg::Error("Solver executable name not provided");
+  std::string name, exe, host;
+
+  if(num == -1){
+    // no solver to run
+    return;
+  }
+  else if(num == -2){
+    // just run local Gmsh client
+  }
+  else if(num >= 0){
+    // run local Gmsh client + solver num
+    name = opt_solver_name(num, GMSH_GET, "");
+    exe = opt_solver_executable(num, GMSH_GET, "");
+    host = opt_solver_remote_login(num, GMSH_GET, "");
+    if(exe.empty()){
+      Msg::Error("Solver executable name not provided");
+      return;
+    }
+  }
+  else{
+    Msg::Error("Unknown client to run in batch mode (%d)", num);
     return;
   }
 
@@ -812,15 +827,21 @@ void solver_batch_cb(void *data)
   onelab::server::instance()->set(n);
 
   // create client
-  onelab::localNetworkClient *c = new gmshLocalNetworkClient(name, exe, host);
-  c->setIndex(num);
-  onelab::string o(c->getName() + "/Action");
+  onelab::localNetworkClient *c = 0;
+  onelab::string o;
+  if(name.size()){
+    c = new gmshLocalNetworkClient(name, exe, host);
+    c->setIndex(num);
+    o = c->getName() + "/Action";
+  }
 
   // initialize
   onelabUtils::runGmshClient("initialize", CTX::instance()->solver.autoMesh);
-  o.setValue("initialize");
-  onelab::server::instance()->set(o);
-  c->run();
+  if(c){
+    o.setValue("initialize");
+    onelab::server::instance()->set(o);
+    c->run();
+  }
 
   // load db
   if(CTX::instance()->solver.autoSaveDatabase){
@@ -830,20 +851,24 @@ void solver_batch_cb(void *data)
 
   // check
   onelabUtils::runGmshClient("check", CTX::instance()->solver.autoMesh);
-  onelabUtils::guessModelName(c);
-  o.setValue("check");
-  onelab::server::instance()->set(o);
-  c->run();
+  if(c){
+    onelabUtils::guessModelName(c);
+    o.setValue("check");
+    onelab::server::instance()->set(o);
+    c->run();
+  }
 
   // compute
   initializeLoops();
   do{
     onelabUtils::runGmshClient("compute", CTX::instance()->solver.autoMesh);
-    onelabUtils::guessModelName(c);
-    o.setValue("compute");
-    onelab::server::instance()->set(o);
-    c->run();
-    onelab::server::instance()->setChanged(false, c->getName());
+    if(c){
+      onelabUtils::guessModelName(c);
+      o.setValue("compute");
+      onelab::server::instance()->set(o);
+      c->run();
+      onelab::server::instance()->setChanged(false, c->getName());
+    }
   } while(incrementLoops());
 
   if(CTX::instance()->solver.autoSaveDatabase ||
diff --git a/doc/texinfo/commandline.texi b/doc/texinfo/commandline.texi
index 7539ea3f6f017d78d27e6ff8154030747e9d5819..05d910c30cfcbbe808e3785b29e86de61e761949 100644
--- a/doc/texinfo/commandline.texi
+++ b/doc/texinfo/commandline.texi
@@ -88,6 +88,8 @@ Always listen to incoming connection requests
 Name of Octave interpreter
 @item -pyinterpreter string
 Name of Python interpreter
+@item -run
+Run ONELAB solver(s)
 @end ftable
  Display options:
 @ftable @code