{"id":11401,"date":"2018-07-31T21:31:36","date_gmt":"2018-07-31T19:31:36","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/"},"modified":"2025-10-24T09:26:21","modified_gmt":"2025-10-24T07:26:21","slug":"a-password-function-for-dmgawk","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/","title":{"rendered":"A password() function for dmgawk"},"content":{"rendered":"<p>A few days ago, as I was preparing a dmawk script for a presentation, I stumbled against another unexpected error.<br \/>\nThe script was attempting to connect to a docbase by providing a docbase name, a user name and a password. But before that, it tested whether a password was provided as a command-line parameter (I know, this is not very secure but it was for demonstration purpose only); if not, it prompted for one using dmawk&#8217;s built-in password() function. The full command was:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [2]\">\necho \"select count(*) from dm_user\" | dmawk -v docbase=dmtest -v username=dmadmin -f select.awk\n<\/pre>\n<p>with select.awk narrowed down to:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1]\">\ncat select.awk\nBEGIN {\n   passwd = password(\"please, enter password: \")\n   print \"password was:\", passwd\n}\n<\/pre>\n<p>The problem was that when piping something into the script, it didn&#8217;t prompt anymore for a password. Without piping, it prompted as expected:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [2]\">\necho \"select count(*) from dm_user\" | dmawk73 -f .\/getpasswd.dmawk\npassword was:\nexiting ...\n<\/pre>\n<p>==&gt; not prompted for password;<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [2]\">\ndmawk73 -f .\/getpasswd.dmawk\nplease, enter password:\npassword was: Supercalifragilisticexpialidocious!\nexiting ...\n<\/pre>\n<p>==&gt; prompted for password;<br \/>\nHere, the alias dmawk73 points to the content server v7.3&#8217;s dmawk, my current version of Documentum contentServer.<br \/>\nNote that the variant below did not work either:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,7]\">\ncat query_file \nselect\n   count(*)\nfrom\ndm_user\n\ndmawk73 -f .\/getpasswd.dmawk &lt; query_file\npassword was:\nexiting ...\n<\/pre>\n<p>==&gt; not prompted for password;<br \/>\nThis proves that what screws up the dmawk&#8217;s password() function is the presence of characters in stdin, whether they come from a pipe or from a redirection.<br \/>\nDid they change (a politically correct way to say &#8220;break&#8221;) something in this version relatively to a previous one ? To be sure, I tried the same tiny script with dmawk from an ancient 5.3 installation I keep around for those puzzling occasions, and guess what ? No special weirdness here, it worked as expected:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [2]\">\ndmadmin@dmclient:~\/getpasswd$ echo \"select count(*) from dm_user\" | dmawk53 -f .\/getpasswd.dmawk\nplease, enter password:\npassword was: Supercalifragilisticexpialidocious\nexiting ...\n<\/pre>\n<p>where the alias dmawk53 points to the content server v5.3&#8217;s dmawk.<br \/>\nA strace on dmawk53 shows that the device \/dev\/tty is read for input:<br \/>\n<code><br \/>\n<strong>open(\"\/dev\/tty\", O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 4<\/strong><br \/>\n...<br \/>\nwrite(4, \"please, enter password: \", 24) = 24<br \/>\nread(4, \"kdkn\", 4096)                  = 4<br \/>\n...<br \/>\nclose(4)                                = 0<br \/>\n...<br \/>\nwrite(1, \"password was: kdkn\", 18)     = 18<br \/>\nwrite(1, \"exiting ...n\", 12)           = 12<br \/>\n<\/code><br \/>\nFor sure, the original behavior was changed somehow around reading from tty and the built-in password() function gets disrupted when something is first input into stdin.<br \/>\nSo how to work around this new pesky issue ? Let&#8217;s see a few solutions. To be clear, I assume from the beginning that security is not a major concern here. Proposed solutions 4, 5 and 6 however are on the same security level as dmawk&#8217;s password() since they restore this function.<\/p>\n<h3>1. Give up piping into dmawk<\/h3>\n<p>This means that it will not be possible to concatenate the awk script to the previous command. If this is acceptable, why not ? dmawk&#8217;s input will have to come from a file, e.g.:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,7,24]\">\ncat query_file \nselect\n   count(*)\nfrom\ndm_user\n\ncat getpasswd_no_pipe.dmawk \nBEGIN {\n   while ((getline &lt; query_file) &gt; 0)\n      query = query \"n\" $0\n   close(query_file)\n   print \"query string is:\", query\n   pp = password(\"please, enter password: \")\n   print \"password was:\", pp\n\n   exit\n\n}\nEND {\n  print \"exiting ...\"\n}\n\nExecution:\ndmadmin@dmclient:~\/getpasswd$ dmawk73 -f getpasswd_no_pipe.dmawk -v query_file=query_file\nquery is: \nselect\n   count(*)\nfrom\ndm_user\n\nplease, enter password: \npassword was: Et tu, Brute?\nexiting ...\n<\/pre>\n<p>If security matters and command concatenation is not needed, the above may be an acceptable work-around.<\/p>\n<h3>2. Using an environment variable<\/h3>\n<p>If security is not significant, the password could be passed in a environment variable, e.g.:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,4]\">\ncat getpasswd_env.dmawk\nBEGIN {\n   cmd = \"echo $password\"\n   cmd | getline pp\n   close(cmd)\n   print \"password was:\", pp\n}\nEND {\n  print \"exiting ...\"\n}\n<\/pre>\n<p>Execution:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,3]\">\nexport password=Supercalifragilisticexpialidocious!\necho \"select count(*) from dm_user\" | dmawk73 -f .\/getpasswd_env.dmawk\npassword was: Supercalifragilisticexpialidocious!\nexiting ...\n<\/pre>\n<p>Here, it is mandatory to use the export statement because dmawk launches a sub-process to read the parent&#8217;s environment variable.<br \/>\nUnlike dmawk, gawk can map the process&#8217; environment into the built-in associative array ENVIRON, which makes accessing $password more elegant and also faster as no sub-process gets spawned:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,3]\">\ncat .\/getpasswd_env.awk\nBEGIN {\n   print \"password was:\", ENVIRON[\"password\"]\n   exit\n}\nEND {\n   print \"exiting...\"\n}\n<\/pre>\n<p>Execution:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [2]\">\necho \"select count(*) from dm_user\" | gawk -f .\/getpasswd_env.awk\npassword was: Supercalifragilisticexpialidocious!\nexiting...\n<\/pre>\n<p>A little digression here while on the subject of environment variables: it&#8217;s a little known fact that the tools iapi and idql support 3 handy but rarely used environment variables: DM_DOCBASE_NAME, DM_USER_NAME and DM_PASSWORD; if those are set, either as a whole or individually, the above utilities can be launched with the corresponding option -ENV_CONNECT_DOCBASE, -ENV_CONNECT_USER_NAME and -ENV_CONNECT_PASSWORD and the corresponding parameter can be omitted. E.g.:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,2,3,4]\">\nexport DM_DOCBASE_NAME=dmtest\nexport DM_USER_NAME=kermit\nexport DM_PASSWORD=conehead\nidql -ENV_CONNECT_DOCBASE_NAME -ENV_CONNECT_USER_NAME -ENV_CONNECT_PASSWORD &lt;\/dev\/null\n   select count(*) from dm_user\n   go\n   quit\nEoQ\nConnected to Documentum Server running Release 7.3.0000.0214  Linux64.Oracle\n1&gt; 2&gt; count(*)              \n----------------------\n                    61\n(1 row affected)\n1&gt; Bye\n<\/pre>\n<p>However, there is no prompt for missing parameters or unset variables and, quite surprisingly, the command fails silently in such cases.<br \/>\nNonetheless, the point here is that we could standardize on these variable names and use them with awk, e.g. (dm)awk would pull out those parameters from the environment as follows:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [3]\">\necho \"select count(*) from dm_user\" | dmawk73 'BEGIN {\n   cmd = \"echo $DM_DOCBASE_NAME $DM_USER_NAME $DM_PASSWORD\"\n   cmd | getline docbase_name dm_user_name passwd\n   print docbase_name, dm_user_name, passwd ? passwd : \"N\/A\"\n   close(cmd)\n}'\ndmtest kermit conehead \n<\/pre>\n<p>whereas gawk could chose to access those environment variables through the built-in ENVIRON associative array:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1]\">\necho \"select count(*) from dm_user\" | gawk 'BEGIN { print ENVIRON[\"DM_DOCBASE_NAME\"], ENVIRON[\"DM_USER_NAME\"], ENVIRON[\"DM_PASSWORD\"] ? ENVIRON[\"DM_PASSWORD\"] : \"N\/A\"}'\ndmtest kermit conehead\n<\/pre>\n<p>which can be more readable in some cases since its indexes are explicitly named vs. positional.<br \/>\nSee section 5 below to know what dmawk and gawk have in common regarding Documentum.<\/p>\n<h3>3. Reading the password from a file<\/h3>\n<p>Here too, let&#8217;s admit that security is not important so a cleartext password could be read from a text file as follows:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,9]\">\ncat getpasswd_from_file.awk\n# Usage:\n#    dmawk -v password_file=... -f getpasswd_from_file.dmawk \nBEGIN {\n   if (!password_file) {\n      print \"missing password_file parameter\"\n      exit\n   }\n   getline pp &lt; password_file\n   close(password_file)\n   print &quot;password was:&quot;, pp\n}\n<\/pre>\n<p>Execution:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,5]\">\ncat password_file\nSupercalifragilisticexpialidocious!\n\necho \"select count(*) from dm_user\" | dmawk -f getpasswd_from_file.awk  -v password_file=password_file\npassword was: Supercalifragilisticexpialidocious!\n<\/pre>\n<p>No surprise here.<\/p>\n<h3>4. Access bash&#8217;s read -s command<\/h3>\n<p>The bash shell has the built-in command read which take the -s option in order to prevent echoing on the screen the entered characters. Unfortunately, while bash is most of the time a login shell, it is not always the subshell invoked when spawning a command, which awk does when executing things like &#8220;cmd | getline&#8221;. Actually, it is \/bin\/sh that is invoked as a subshell under Linux, which is a sym link to \/bin\/dash (at least the Ubuntu 16.04 and 18.04 I&#8217;m using here; under Centos, \/usr\/bin\/sh is symlinked to \/usr\/bin\/bash), a much smaller shell than bash and supposedly faster. So, how to force bash as a subshell ?<br \/>\nI could not find any system setting to configure the choice of the subshell. Obviously, changing the \/bin\/sh symlink and making it point to \/bin\/bash works indeed but it is a system-wide change and it is not recommended because of possible compatibility issues.<br \/>\nThe solution is to explicitly tell the subshell to make bash execute the read. But it is not enough, we also need to explicitly tell read to get its input from \/dev\/tty otherwise it gets messed up with any piped or redirected input. Here is a solution:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,10,11,14,18]\">\ncat getpasswd_tty.dmawk\nBEGIN {\n   pp = getpassword(\"please, enter password: \")\n   print \"npassword was:\", pp\n   exit\n}\nEND {\n  print \"exiting ...\"\n}\nfunction getpassword(prompt     , cmd, passwd) {\n   cmd = \"\/bin\/bash -c 'read -s -p \"\" prompt \"\" passwd &lt; \/dev\/tty; echo $passwd&#039;&quot;\n   cmd | getline passwd\n   close(cmd)\n   return passwd\n}\n\nExecution:\necho &quot;select count(*) from dm_user&quot; | dmawk -f  getpasswd_tty.dmawk \nplease, enter password: password: \npassword was: AreYo7Kidd8ngM3?\nexiting ...\n<\/pre>\n<p>Line 11 invokes bash from whatever subshell is launched by dmawk, and asks it to execute the read built-in without echo, with the given prompt, and with its input coming directly from the device \/dev\/tty.<br \/>\nOn line 10, note the function getpassword&#8217;s formal parameters cmd and passwd; since the function is called without any effective value for those, they are considered as local variables; this is a common idiom in awk where all variables are global and come to existence as soon as they are referenced.<br \/>\nUnder Centos, where \/usr\/bin\/bash is also invoked as a subshell, line 11 can be slightly simplified:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight:\">\n   cmd = \"'read -s -p \"\" prompt \"\" passwd &lt; \/dev\/tty; echo $passwd&#039;&quot;&quot;\n<\/pre>\n<p>This work-around is the easiest and closest to the original built-in password() function.<\/p>\n<h3>5. Implement password() in dmgawk<\/h3>\n<p>Those who have read my blog <a title=\"Gawk extension\" href=\"https:\/\/www.dbi-services.com\/blog\/adding-a-documentum-extension-to-gawk-part-i\/\" target=\"_blank\" rel=\"noopener\">here<\/a> know that we have now a much more powerful implementation of awk in our toolbox, GNU gawk, which we can extend to suit our needs. The above blog describes how to extend gawk with a connectivity to Documentum docbases; I jokingly named the resulting awk dmgawk. As glibc includes the getpass() function just for this purpose, why not use the same approach and add to dmgawk a sensible password() function around C&#8217;s getpass() that works as before ? Let&#8217;s put our money where our mouth is and implement this function in dmgawk. In truth, it should be noted that getpass() is marked as being obsolete so this alternative should be considered as a temporary work-around.<br \/>\nI won&#8217;t copy here all the steps from the above blog though; here are only the distinctive ones.<br \/>\nThe interface&#8217;s source:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1]\">\ncat ~\/dmgawk\/gawk-4.2.1\/extension\/password.c\n\/*\n * password.c - Builtin function that provide an interface to the getpass() function;\n * see dmapp.h for description of functions;\n *\n * C. Cervini\n * dbi-services.com\n * 7\/2018\n *\/\n#ifdef HAVE_CONFIG_H\n#include \n#endif\n\n#include \"gawkapi.h\"\n\n#include \"gettext.h\"\n#define _(msgid)  gettext(msgid)\n#define N_(msgid) msgid\n\nstatic const gawk_api_t *api;   \/* for convenience macros to work *\/\nstatic awk_ext_id_t ext_id;\nstatic const char *ext_version = \"password extension: version 1.0\";\nstatic awk_bool_t (*init_func)(void) = NULL;\n\nint plugin_is_GPL_compatible;\n\n\/*  do_password *\/\nstatic awk_value_t *\ndo_password(int nargs, awk_value_t *result, struct awk_ext_func *unused) {\n   awk_value_t prompt;\n   char *passwd;\n\n   assert(result != NULL);\n\n   if (get_argument(0, AWK_STRING, &amp;prompt)) {\n      passwd = getpass(prompt.str_value.str);\n   }\n   else passwd = getpass(\"\");\n\n   make_const_string(passwd == NULL ? \"\" : passwd, strlen(passwd), result);\n   return result;\n}\n\n\/*\nthese are the exported functions along with their min and max arities;\nlet's make the prompt parameter optional, as in dmawk;\n*\/\nstatic awk_ext_func_t func_table[] = {\n        { \"password\", do_password, 1, 0, awk_false, NULL },\n};\n\n\/* define the dl_load function using the boilerplate macro *\/\n\ndl_load_func(func_table, password, \"\")\n<\/pre>\n<p>Compilation steps:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,2,3,18,20,25,26,27,29,32]\">\ncd ~\/dmgawk\/gawk-4.2.1\/extension\nvi Makefile.am\nappend the new library to the pkgextension_LTLIBRARIES list:\npkgextension_LTLIBRARIES =      \n        filefuncs.la    \n        fnmatch.la      \n        fork.la         \n        inplace.la      \n        intdiv.la       \n        ordchr.la       \n        readdir.la      \n        readfile.la     \n        revoutput.la    \n        revtwoway.la    \n        rwarray.la      \n        time.la         \n        dctm.la         \n        password.la\n\nlater:\ndctm_la_SOURCES       = dctm.c\ndctm_la_LDFLAGS       = $(MY_MODULE_FLAGS)\ndctm_la_LIBADD        = $(MY_LIBS)\n\npassword_la_SOURCES  = password.c\npassword_la_LDFLAGS  = $(MY_MODULE_FLAGS)\npassword_la_LIBADD   = $(MY_LIBS)\n\nrun the make command:\nmake\n\ngo one level up and run the make command again:\nmake\n<\/pre>\n<p>At this point, the new gawk is ready for use. Let&#8217;s test it:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1]\">\ncat getpasswd.awk\n@load \"password\"\n\nBEGIN {\n   passwd = password(\"please, enter password: \")\n   print \"password was:\", passwd\n}\n\nEND {\n   print \"exiting...\"\n}\n<\/pre>\n<p>Execution:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [2]\">\nAWKLIBPATH=~\/dmgawk\/gawk-4.2.1\/extension\/.libs echo \"select count(*) from dm_user\" | ~\/dmgawk\/gawk-4.2.1\/gawk -f .\/getpasswd.awk \nplease, enter password: \npassword was: precipitevolissimevolmente\nexiting...\n<\/pre>\n<p>If all is good, install the new extension system-wide as follows:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [2,4,6]\">\ncd ~\/dmgawk\/gawk-4.2.1\nsudo make install\n\nmake an alias to the new gawk:\nalias dmgawk=\/usr\/local\/bin\/gawk\nThe usage is simplified now:\necho \"select count(*) from dm_user\" | dmgawk -f .\/getpasswd.awk\nplease, enter password: \npassword was: humptydumpty\nexiting...\n<\/pre>\n<p>dmgawk looks more and more like a valuable substitute for dmawk. What gets broken in dmawk can be fixed by dmgawk.<\/p>\n<h3>6. And in python ?<\/h3>\n<p>Those who use python for their Documentum administration tasks, extended with the Documentum connectivity as proposed in my blog <a title=\"Python Extension\" href=\"https:\/\/www.dbi-services.com\/blog\/adding-a-documentum-extension-into-python\/\" target=\"_blank\" rel=\"noopener\">here<\/a>, are even luckier because python has a library for just about everything but the kitchen sink, and an interface to C&#8217;s getpass(), appropriately named getpass(), already exists, see <a title=\"getpass python library\" href=\"https:\/\/docs.python.org\/3.7\/library\/getpass.html\" target=\"_blank\" rel=\"noopener\">here<\/a>. Therefore, there is no need to write one using e.g. ctypes.  Here is how to call the python&#8217;s getpass():<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [1,4,6,12]\">\ncat getpasswd.py \n#!\/usr\/bin\/python\n\nimport getpass\n\npasswd = getpass.getpass(prompt = \"Please, enter password: \")\nprint(\"The password is: \" + passwd)\n\nExecution:\necho \"select count(*) from dm_user\" | .\/getpasswd.py\nPlease, enter password: \nThe password is: Did the quick brown fox jump over the lazy dog ?\n<\/pre>\n<p>No muss, no fuss here.<\/p>\n<h3>Conclusion<\/h3>\n<p>It&#8217;s quite interesting to see how basic things that we take for granted get broken from one Documentum release to another. On the bright side though, those little frustrations gives us the opportunity to look for work-arounds, and write blogs about them ;-). I am eager to find the next dysfunction and pretty confident that Documentum will not be disappoint me in this respect.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few days ago, as I was preparing a dmawk script for a presentation, I stumbled against another unexpected error. The script was attempting to connect to a docbase by providing a docbase name, a user name and a password. But before that, it tested whether a password was provided as a command-line parameter (I [&hellip;]<\/p>\n","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[525],"tags":[],"type_dbi":[],"class_list":["post-11401","post","type-post","status-publish","format-standard","hentry","category-enterprise-content-management"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>A password() function for dmgawk - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A password() function for dmgawk\" \/>\n<meta property=\"og:description\" content=\"A few days ago, as I was preparing a dmawk script for a presentation, I stumbled against another unexpected error. The script was attempting to connect to a docbase by providing a docbase name, a user name and a password. But before that, it tested whether a password was provided as a command-line parameter (I [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-07-31T19:31:36+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-24T07:26:21+00:00\" \/>\n<meta name=\"author\" content=\"Middleware Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Middleware Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/\"},\"author\":{\"name\":\"Middleware Team\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1\"},\"headline\":\"A password() function for dmgawk\",\"datePublished\":\"2018-07-31T19:31:36+00:00\",\"dateModified\":\"2025-10-24T07:26:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/\"},\"wordCount\":1351,\"commentCount\":0,\"articleSection\":[\"Enterprise content management\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/\",\"name\":\"A password() function for dmgawk - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2018-07-31T19:31:36+00:00\",\"dateModified\":\"2025-10-24T07:26:21+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A password() function for dmgawk\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1\",\"name\":\"Middleware Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"caption\":\"Middleware Team\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/middleware-team\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"A password() function for dmgawk - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/","og_locale":"en_US","og_type":"article","og_title":"A password() function for dmgawk","og_description":"A few days ago, as I was preparing a dmawk script for a presentation, I stumbled against another unexpected error. The script was attempting to connect to a docbase by providing a docbase name, a user name and a password. But before that, it tested whether a password was provided as a command-line parameter (I [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/","og_site_name":"dbi Blog","article_published_time":"2018-07-31T19:31:36+00:00","article_modified_time":"2025-10-24T07:26:21+00:00","author":"Middleware Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Middleware Team","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/"},"author":{"name":"Middleware Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1"},"headline":"A password() function for dmgawk","datePublished":"2018-07-31T19:31:36+00:00","dateModified":"2025-10-24T07:26:21+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/"},"wordCount":1351,"commentCount":0,"articleSection":["Enterprise content management"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/","url":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/","name":"A password() function for dmgawk - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2018-07-31T19:31:36+00:00","dateModified":"2025-10-24T07:26:21+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/a-password-function-for-dmgawk\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"A password() function for dmgawk"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1","name":"Middleware Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","caption":"Middleware Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/middleware-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11401","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=11401"}],"version-history":[{"count":1,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11401\/revisions"}],"predecessor-version":[{"id":41174,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/11401\/revisions\/41174"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=11401"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=11401"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=11401"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=11401"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}