diff --git a/doc/src/variable.txt b/doc/src/variable.txt
index c0851464c3f14e11629b8e65ee58a171499a4e45..3f432b3778cc8c5528c12cab961ffe995c8ea29c 100644
--- a/doc/src/variable.txt
+++ b/doc/src/variable.txt
@@ -296,10 +296,11 @@ list of runs (e.g. 1000) without having to list N strings in the input
 script.
 
 For the {string} style, a single string is assigned to the variable.
-The only difference between this and using the {index} style with a
-single string is that a variable with {string} style can be redefined.
-E.g. by another command later in the input script, or if the script is
-read again in a loop.
+Two differences between this this and using the {index} style exist:
+a variable with {string} style can be redefined, e.g. by another command later
+in the input script, or if the script is read again in a loop. The other
+difference is that {string} performs variable substitution even if the
+string parameter is quoted.
 
 For the {format} style, an equal-style variable is specified along
 with a C-style format string, e.g. "%f" or "%.10g", which must be
diff --git a/src/variable.cpp b/src/variable.cpp
index b5c19a48439cd2342273e7af4b7d21936ffe9bd2..86296b4b402e4c066d2692d5362d579be635c54d 100644
--- a/src/variable.cpp
+++ b/src/variable.cpp
@@ -284,12 +284,21 @@ void Variable::set(int narg, char **arg)
 
   } else if (strcmp(arg[1],"string") == 0) {
     if (narg != 3) error->all(FLERR,"Illegal variable command");
+
+    int maxcopy = strlen(arg[2]) + 1;
+    int maxwork = maxcopy;
+    char *scopy = new char[maxcopy];
+    char *work = new char[maxwork];
+    strcpy(scopy,arg[2]);
+    input->substitute(scopy,work,maxcopy,maxwork,1);
+    delete [] work;
+
     int ivar = find(arg[0]);
     if (ivar >= 0) {
       if (style[ivar] != STRING)
         error->all(FLERR,"Cannot redefine variable as a different style");
       delete [] data[ivar][0];
-      copy(1,&arg[2],data[ivar]);
+      copy(1,&scopy,data[ivar]);
       replaceflag = 1;
     } else {
       if (nvar == maxvar) grow();
@@ -298,8 +307,9 @@ void Variable::set(int narg, char **arg)
       which[nvar] = 0;
       pad[nvar] = 0;
       data[nvar] = new char*[num[nvar]];
-      copy(1,&arg[2],data[nvar]);
+      copy(1,&scopy,data[nvar]);
     }
+    delete [] scopy;
 
   // GETENV
   // remove pre-existing var if also style GETENV (allows it to be reset)
diff --git a/src/variable.h b/src/variable.h
index a74cdba980f4cee3c75486a08706e3c3ba4f96ca..b20eb7e6b93e566f77d5421e820e59eb1a9b79b1 100644
--- a/src/variable.h
+++ b/src/variable.h
@@ -16,6 +16,7 @@
 
 #include <cstdlib>
 #include "pointers.h"
+#include "input.h"
 
 namespace LAMMPS_NS {