diff --git a/src/utils/BuildInfo.cpp b/src/utils/BuildInfo.cpp
index 7162aeccf69a7b5e6420e23ae7dca6cea6ced9b1..38d46007ef6cfcf470051e8546714db7041a7852 100644
--- a/src/utils/BuildInfo.cpp
+++ b/src/utils/BuildInfo.cpp
@@ -22,7 +22,7 @@ std::string
 BuildInfo::compiler()
 {
   std::stringstream compiler_info;
-  compiler_info << PUGS_BUILD_COMPILER << " (" << PUGS_BUILD_COMPILER_VERSION << ")" << std::ends;
+  compiler_info << PUGS_BUILD_COMPILER << " (" << PUGS_BUILD_COMPILER_VERSION << ")";
   return compiler_info.str();
 }
 
diff --git a/src/utils/ConsoleManager.cpp b/src/utils/ConsoleManager.cpp
index 666caa1b17c5bb397e592132febeabab4846732f..f55004ac7dd2181256404b486ad1eaa0c05abd85 100644
--- a/src/utils/ConsoleManager.cpp
+++ b/src/utils/ConsoleManager.cpp
@@ -11,12 +11,9 @@ ConsoleManager::isTerminal(std::ostream& os)
 void
 ConsoleManager::init(bool colorize)
 {
-  std::cout << "Console management: color ";
   if (colorize) {
     rang::setControlMode(rang::control::Force);
-    std::cout << rang::style::bold << rang::fgB::green << "enabled" << rang::fg::reset << rang::style::reset << '\n';
   } else {
     rang::setControlMode(rang::control::Off);
-    std::cout << "disabled\n";
   }
 }
diff --git a/src/utils/FPEManager.cpp b/src/utils/FPEManager.cpp
index 7430b5bbcc8c17d31b3a9508a170bfb3ed525632..89a75d7c77e8649b6710e32f6d89ed5e9f85c1c0 100644
--- a/src/utils/FPEManager.cpp
+++ b/src/utils/FPEManager.cpp
@@ -62,16 +62,12 @@ fedisableexcept(unsigned int excepts)
 void
 FPEManager::enable()
 {
-  std::cout << "FE management: " << rang::style::bold << rang::fgB::green << "enabled" << rang::fg::reset
-            << rang::style::reset << '\n';
   ::feenableexcept(MANAGED_FPE);
 }
 
 void
 FPEManager::disable()
 {
-  std::cout << "FE management: " << rang::style::bold << rang::fgB::red << "disabled" << rang::fg::reset
-            << rang::style::reset << '\n';
   ::fedisableexcept(MANAGED_FPE);
 }
 
@@ -79,15 +75,11 @@ FPEManager::disable()
 
 void
 FPEManager::enable()
-{
-  std::cout << "FE management: enabled " << rang::fg::red << "[not supported]" << rang::fg::reset << '\n';
-}
+{}
 
 void
 FPEManager::disable()
-{
-  std::cout << "FE management: disable " << rang::fg::red << "[not supported]" << rang::fg::reset << '\n';
-}
+{}
 
 #endif   // PUGS_HAS_FENV_H
 
diff --git a/src/utils/PugsUtils.cpp b/src/utils/PugsUtils.cpp
index d54bd333f93107a1e093038764ebe7f088ace9df..43e9cd20fbd4c15089aab4db18791453582b6a38 100644
--- a/src/utils/PugsUtils.cpp
+++ b/src/utils/PugsUtils.cpp
@@ -24,38 +24,63 @@
 // This function cannot be unit-tested: run once when pugs starts
 
 std::string
-initialize(int& argc, char* argv[])
+pugsVersion()
 {
-  parallel::Messenger::create(argc, argv);
+  std::stringstream os;
 
-  std::cout << "Pugs version: " << rang::style::bold << RevisionInfo::version() << rang::style::reset << '\n';
+  os << "pugs version: " << rang::style::bold << RevisionInfo::version() << rang::style::reset << '\n';
 
-  std::cout << "-------------------- " << rang::fg::green << "git info" << rang::fg::reset
-            << " -------------------------" << '\n';
-  std::cout << "tag:  " << rang::style::bold << RevisionInfo::gitTag() << rang::style::reset << '\n';
-  std::cout << "HEAD: " << rang::style::bold << RevisionInfo::gitHead() << rang::style::reset << '\n';
-  std::cout << "hash: " << rang::style::bold << RevisionInfo::gitHash() << rang::style::reset << "  (";
+  os << "-------------------- " << rang::fg::green << "git info" << rang::fg::reset << " -------------------------"
+     << '\n';
+  os << "tag:  " << rang::style::bold << RevisionInfo::gitTag() << rang::style::reset << '\n';
+  os << "HEAD: " << rang::style::bold << RevisionInfo::gitHead() << rang::style::reset << '\n';
+  os << "hash: " << rang::style::bold << RevisionInfo::gitHash() << rang::style::reset << "  (";
 
   if (RevisionInfo::gitIsClean()) {
-    std::cout << rang::fgB::green << "clean" << rang::fg::reset;
+    os << rang::fgB::green << "clean" << rang::fg::reset;
   } else {
-    std::cout << rang::fgB::red << "dirty" << rang::fg::reset;
+    os << rang::fgB::red << "dirty" << rang::fg::reset;
   }
-  std::cout << ")\n";
-  std::cout << "-------------------- " << rang::fg::green << "build info" << rang::fg::reset
-            << " -----------------------" << '\n';
-  std::cout << "type:     " << rang::style::bold << BuildInfo::type() << rang::style::reset << '\n';
-  std::cout << "compiler: " << rang::style::bold << BuildInfo::compiler() << rang::style::reset << '\n';
-  std::cout << "kokkos:   " << rang::style::bold << BuildInfo::kokkosDevices() << rang::style::reset << '\n';
-  std::cout << "MPI:      " << rang::style::bold << BuildInfo::mpiLibrary() << rang::style::reset << '\n';
-  std::cout << "PETSc:    " << rang::style::bold << BuildInfo::petscLibrary() << rang::style::reset << '\n';
-  std::cout << "-------------------------------------------------------\n";
+  os << ")\n";
+  os << "-------------------------------------------------------";
+
+  return os.str();
+}
+
+std::string
+pugsBuildInfo()
+{
+  std::ostringstream os;
+
+  os << "-------------------- " << rang::fg::green << "build info" << rang::fg::reset << " -----------------------"
+     << '\n';
+  os << "type:     " << rang::style::bold << BuildInfo::type() << rang::style::reset << '\n';
+  os << "compiler: " << rang::style::bold << BuildInfo::compiler() << rang::style::reset << '\n';
+  os << "kokkos:   " << rang::style::bold << BuildInfo::kokkosDevices() << rang::style::reset << '\n';
+  os << "MPI:      " << rang::style::bold << BuildInfo::mpiLibrary() << rang::style::reset << '\n';
+  os << "PETSc:    " << rang::style::bold << BuildInfo::petscLibrary() << rang::style::reset << '\n';
+  os << "-------------------------------------------------------";
+
+  return os.str();
+}
+
+std::string
+initialize(int& argc, char* argv[])
+{
+  parallel::Messenger::create(argc, argv);
 
   std::string filename;
   {
-    CLI::App app{"Pugs help"};
+    CLI::App app{"pugs help"};
+
+    app.add_option("filename", filename, "pugs script file")->check(CLI::ExistingFile)->required();
 
-    app.add_option("filename", filename, "pugs script file")->required()->check(CLI::ExistingFile);
+    app.set_version_flag("-v,--version", []() {
+      ConsoleManager::init(true);
+      std::stringstream os;
+      os << pugsVersion() << '\n' << pugsBuildInfo();
+      return os.str();
+    });
 
     int threads = -1;
     app.add_option("--threads", threads, "Number of Kokkos threads")
diff --git a/src/utils/PugsUtils.hpp b/src/utils/PugsUtils.hpp
index ef4eeb72c340b8a6ca654d001c32390973b63c55..54bcc6d0567b00fda6a25d865d7cb0b759bfb2bd 100644
--- a/src/utils/PugsUtils.hpp
+++ b/src/utils/PugsUtils.hpp
@@ -21,6 +21,10 @@ parallel_reduce(size_t size, const ArrayType& array, ReturnType& value, const st
   Kokkos::parallel_reduce(label, size, array, value);
 }
 
+std::string pugsBuildInfo();
+
+std::string pugsVersion();
+
 std::string initialize(int& argc, char* argv[]);
 
 void finalize();
diff --git a/src/utils/SignalManager.cpp b/src/utils/SignalManager.cpp
index ab08424fa2731bc62d84b461cea850878da9514b..399f3164c2046f4ec25a009160a6f01b11da85ef 100644
--- a/src/utils/SignalManager.cpp
+++ b/src/utils/SignalManager.cpp
@@ -114,11 +114,5 @@ SignalManager::init(bool enable)
     std::signal(SIGINT, SignalManager::handler);
     std::signal(SIGABRT, SignalManager::handler);
     std::signal(SIGPIPE, SignalManager::handler);
-
-    std::cout << "Signal management: " << rang::style::bold << rang::fgB::green << "enabled" << rang::fg::reset
-              << rang::style::reset << '\n';
-  } else {
-    std::cout << "Signal management: " << rang::style::bold << rang::fgB::red << "disabled" << rang::fg::reset
-              << rang::style::reset << '\n';
   }
 }