Escape variable in Jenkins shell execution - bash

We use Jenkins to run some Wordpress CLI stuff for us, and I would like to pass in some PHP to the Wordpress CLI. For example:
cd wordpress && wp core config --skip-check --dbhost=dbhost --dbname=dbname --dbuser=user --dbpass=pass --extra-php <<PHP
define('HOST', $_SERVER['HTTP_HOST']);
PHP
Jenkins interprets the $_SERVER and I'm left with ['HTTP_HOST']. How can I escape $_SERVER?
I've tried doing define('HOST', \$_SERVER['HTTP_HOST']);, but that still gets interpreted as a variable.

Figured it out... Wrap the first section of defining HEREDOC in double quotes.
cd wordpress && wp core config --skip-check --dbhost=dbhost --dbname=dbname --dbuser=user --dbpass=pass --extra-php <<"PHP"
define('HOST', $_SERVER['HTTP_HOST']);
PHP
It no longer interprets $_SERVER.

Related

Bash - Gitlab CI not converting variable to a string

I am using GitLab to deploy a project and have some environmental variables setup in the GitLab console which I use in my GitLab deployment script below:
- export S3_BUCKET="$(eval \$S3_BUCKET_${CI_COMMIT_REF_NAME^^})"
- aws s3 rm s3://$S3_BUCKET --recursive
My environmental variables are declared like so:
Key: s3_bucket_development
Value: https://dev.my-bucket.com
Key: s3_bucket_production
Value: https://prod.my-bucket.com
The plan is that it grabs the bucket URL from the environmental variables depending on which branch is trying to deploy (CI_COMMIT_REF_NAME).
The problem is that the S3_BUCKET variable does not seem to get set properly and I get the following error:
> export S3_BUCKET=$(eval \$S3_BUCKET_${CI_COMMIT_REF_NAME^^})
> /scripts-30283952-2040310190/step_script: line 150: https://dev.my-bucket.com: No such file or directory
It looks like it picks up the environmental variable value fine but does not set it properly - any ideas why?
It seems like you are trying to get the value of the variables S3_BUCKET_DEVELOPMENT and S3_BUCKET_PRODUCTION based on the value of CI_COMMIT_REF_NAME, you can do this by using parameter indirection:
$ a=b
$ b=c
$echo "${!a}" # c
and in your case, you would need a temporary variable as well, something like this might work:
- s3_bucket_variable=S3_BUCKET_${CI_COMMIT_REF_NAME^^}
- s3_bucket=${!s3_bucket_variable}
- aws s3 rm "s3://$s3_bucket" --recursive
You are basically telling bash to execute command, named https://dev.my-bucket.com, which obviously doesn't exist.
Since you want to assign output of command when using VAR=$(command) you should probably use echo
export S3_BUCKET=$(eval echo \$S3_BUCKET_${CI_COMMIT_REF_NAME^^})
Simple test:
VAR=HELL; OUTPUT="$(eval echo "\$S${VAR^^}")"; echo $OUTPUT
/bin/bash
It dynamically creates SHELL variable, and then successfully prints it

How to get Artisan::call('command:name') output in a variable?

Is it possible to get $output as follows:
$output = Artisan::call('command:name');
I have tried many solutions in different posts but it didn't work on my Laravel 5.2.
You can call the output method on Artisan
Artisan::call('command:name');
$output = Artisan::output();
Make sure you are using one of the available output methods like $this->line('output'); in the actual Artisan command. More info in the docs.
There are several ways to accomplish this, but as your are using such old version of Laravel maybe the best for your case is one that will not require a rewrite when you finally migrate to a newer version. Have you tried perhaps the vanilla PHP methods system, shell_exec and passthru?
system will return just the last line of the command on succes and FALSE on failure
shell_exec will return the entire output but without a way to fetch the output status code
passthru will not return any output instead it will output all on stdout. Although it can be put into a variable using output cache methods (i.e. ob_start and ob_get_contents)
In any case you should call those methods using as argument the CLI version of the command you wish to run:
$output = shell_exec("php artisan command:here");
P.S. If you by any chance have a user input that you want to pass as parameter to a artisan command, make sure you escape it with escapeshellcmd first.

How to debug Symfony command using Xdebug and phpStorm?

First of all let's start saying I am running the whole project in a Docker container and that means I don't have anything installed on the host.
Having that I am trying to debug a Symfony command which is kind of CLI script with the difference it's not being called as php script.php but as bin/console command.
What does the console file has inside it? See below:
#!/usr/bin/env php
<?php
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Debug\Debug;
set_time_limit(0);
/** #var Composer\Autoload\ClassLoader $loader */
$loader = require __DIR__.'/../app/autoload.php';
$input = new ArgvInput();
$env = $input->getParameterOption(['--env', '-e'], getenv('SYMFONY_ENV') ?: 'dev');
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(['--no-debug', '']) && $env !== 'prod';
if ($debug) {
    Debug::enable();
}
$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->run($input);
I have Xdebug installed and configured, I have phpStorm configured as well and that means using the browser (and the extension to enable/disable) I can debug whatever I want.
Typically this is how the command is executed from the console (bash):
<path_to_symfony>/bin/console quote:notify -d 120 -e <some_email>
Options are optional here and that means I can call the same as:
<path_to_symfony>/bin/console quote:notify
It will work both ways. I am using the docs from here to debug such command. Now this is how I am setting up the IDE to debug a Symfony command:
Go to Run/Debug Configuration
Click on Add button (little green + symbol)
Choose PHP Script
Name it as SF Command
At File box I wrote bin/console
At Arguments box I wrote quote:notify (which is my command)
But the IDE says first: Error: file not specified or invalid and then when I try to execute the command it says it's not a valid configuration. (also notice the little "X" which should means something is wrong)
What I am missing here? Can I get some help here? I am using the latest version of phpStorm.

How can I get $ not escaped in application default jvm args for gradle?

Using the application task I am specifying:
applicationDefaultJvmArgs = ['$DEBUG_OPTS',
'-Djava.library.path=${ZMQ_LIB_PATH}']
In the generated start scripts I see:
DEFAULT_JVM_OPTS='"\$DEBUG_OPTS" "-Djava.library.path=\${ZMQ_LIB_PATH}"'
I don't want the \$ in there. I tried using '$$DEBUG_OPTS' and also '\$DEBUG_OPTS' but got the same result. What is the right way to escape the $ so it ends up in the script without a backslash in front of it?
I had a similar issue, trying to add a commandline parameter $1 in there. With some googling came up with this solution, fixing the script after the fact.
applicationDefaultJvmArgs=['-Dmy.property=DOLLARONE']
...
startScripts{
doLast{
def bashFile = new File(getOutputDir(),applicationName)
String bashContent = bashFile.text
bashFile.text = bashContent.replaceFirst('DOLLARONE', Matcher.quoteReplacement('$1'))
}
}
The StartScriptGenerator code implies that '$' will be unconditionally replaced by the '\$'.
I assume that your intention is to use '$' character for shell parameters extension but I would like to point out that such usage (if permitted by the gradle task that generates the scripts) is not interoperable between bash and bat scripts - in the bash it will be used for shell parameters extension but in the bat it will have no meaning.
For Kotlin build script the solution could look like:
tasks.named<CreateStartScripts>("startScripts") {
doLast {
unixScript.writeText(unixScript.readText().replace("{{APP_HOME}}", "\${APP_HOME}"))
windowsScript.writeText(windowsScript.readText().replace("{{APP_HOME}}", "%APP_HOME%"))
}
}

How to pass variable in bash for php command

On bash funcion I need pass varible por a external command (php)
panel=$(php -r '$ini_array = parse_ini_file("/root/.name/name.ini");echo $ini_array['panel'];')
Work properly.
But I need pass path on variable and key of array also.
Try several form but all fails. '', "", ...
php -r '$ini_array = parse_ini_file(`$sPath`);echo $ini_array["$sKey"];'
It's possible?
Pass the variable through the environment, and retrieve it from the environment on the PHP side.
sPath=$sPath sKey=$sKey \
php -r '$ini_array = parse_ini_file($_ENV["sPath"]);echo $ini_array[$_ENV["sKey"]];'
The initial sPath=$sPath and sKey=$sKey are not necessary if you have used export to put your shell variables in the environment already.

Resources