Simulate `cd` command with PHP - php

I am making a CLI-tool for work using the symfony/console composer package. (Much like laravel/installer)
The goal of this tool is to improve the daily workflow for my coworkers.
My [COMPANY] install command installs all active repositories in the current working directory. I save this directory in a configuration file on the home directory.
I now want to add a [COMPANY] cd command which should simulate an actual cd command by changing the current directory of my terminal to the install directory. So far, I have tried the following:
What I already tried
protected function handle(): void
{
$config = new Config;
$path = $config->get('directory');
if (is_null($path)) {
$this->error("It seems like you didn't install the [COMPANY] projects. Take a look at the `[COMPANY] install` command.");
exit;
}
// These options do not work because they are executed in an isolated sub-process.
chdir($path);
exec("cd $path");
shell_exec("cd $path");
$this->info("Changed working directory to $path");
}
The chdir() method only changes the working directory of the current php script. While exec() starts a completely isolated process.
Desired behaviour
~ cd ~/Development/Company
~/Development/Company company install
~/Development/Company cd ~
~ company cd
~/Development/Company
My question: Is this kind of behavior even possible with PHP? And if so, how can I achieve this.
Thanks in advance.

No, you cannot change the working directory of a terminal by running a script in it.
cd is a command built into your shell, not an external command in e.g. /bin.

Related

bash script creating virtual filesystem and mounting it on a specific directory

here is my problem: i would like to create a directory and limit it size using this method.
The thing is when i try it via cli its working perfectly (the file system is mounted on the newly created directory with its size limit), however when i put it in a bash script the directory is created but not with its size limit.
Here is my script.sh:
# !/bin/bash
# Set default parameters
limited_directory_name=$1
size=$2
# Setting path
parent_path="/path/to/directory/parent/"
directory_path="$parent_path$limited_directory_name"
# Creating directory/mountpoint
mkdir "$directory_path"
#Creating a file full of /dev/zero
limited_size_file="$directory_path.ext4"
touch "$limited_size_file"
dd if=/dev/zero of="$limited_size_file" bs="$size" count=1
#Formating the file
sudo mkfs.ext4 "$limited_size_file"
#Mount the disk
sudo mount -o loop,rw,usrquota,grpquota "$limited_size_file" "$directory_path"
I believe (pretty sure actually), that the problem is in these two last lines
sudo mkfs.ext4 "$limited_size_file"
or/and
sudo mount -o loop,rw,usrquota,grpquota "$limited_size_file" "$directory_path"
because as i said, the file and directory are created but just not with the size limit.
Also when i try to delete the directory ($directory_path/) after executing those command via cli i got : rm: cannot delete '$directory_path/': Device or resource busy, that i dont get when trying to delete it after executing the script. So i guess that the file system is not mounted when executing the script, and the problem is probably in the last two lines. I dont know if its has something to do with the way of using sudo inside a script or just something with mounting a file system inside a bash script.
I just wanna say that i am fairly new to bash scripting and i am sorry if my mistake is something like an obvious (noob) error. You can also say if i can improve my question in any way and i apologize if it's not clear enough.
And one last thing, i have tried different syntax for the last two line like:
sudo $(mkfs.ext4 "$limited_size_file")
or
sudo `mkfs.ext4 "$limited_size_file"`
or just
mkfs.ext4 "$limited_size_file" without sudo.
But nothing seems to work. I am using debian 10 btw and im calling the script like this in a PHP page (if it can help):
exec("myscript.sh $dname $dsize");

Running Hugo from a PHP exec() function

I'm attempting to setup a continuous deployment script for Hugo on a LAMP stack server, and the last snag I'm running into is getting Hugo to run.
The Background
I have Hugo and PHP installed on a VPS, and for my app, two directories:
public, where my actual site lives.
hugo, where my entire Hugo setup gets pulled into from GitHub.
I'm using a GitHub webhook to ping my deploy.php script when I merge into the master branch. Here's the relevant part of that script:
// 1. Pull the latest build from GitHub
exec('cd /path/to/hugo && git fetch --all && git reset --hard origin/master');
// 2. Run Hugo to compile any new posts and pages into HTML
exec('cd /path/to/hugo && hugo');
// 3. Copy the files in the /public directory from Hugo into the /public app directory
exec('cd /path/to/hugo && cp -r /path/to/hugo/public/. public');
What's happening
Items 1 and 3 run. Item 2 does not.
More clearly stated: the latest build pulls from GitHub, and any files I've built ahead of time are copied from the Hugo build into the /public directory.
I cannot get hugo to run via exec(), though, and I'm not entirely sure why.
If I SSH into the server in a terminal window, cd into the /path/to/hugo directory, and run hugo there, everything compiles as expected, which eliminates things like, "Maybe Hugo is installed wrong" or "Maybe Hugo isn't accessible in that directory".
So... what am I missing? Thanks in advance!
Check if this is a path issue, meaning by default, a bash session won't execute a program just because you are in the right folder: you have to specify its path (in your case: the current folder)
That means: replace && hugo with && ./hugo
Or, as the OP Chris Ferdinandi did (comments), you can use an absolute path:
I ssh-ed into the server and ran which hugo to get the appropriate path, and replaced && hugo with that.

Providing HTTP read-only access to svn checkout on a PHP server?

I have some Subversion repositories (originally created with svnadmin) on a server; there is authenticated SSH read+write access via svn+ssh://. For certain of those SVN repositories, I would like to allow an anonymous read-only access via http://. The problem is I don't have administrative properties on that server, so I cannot really mess with server setups or run svnserve, but I can have PHP scripts. So I was wondering if there is some solution, hopefully in PHP, that would allow me to do that (implement a "bridge" to a subversion repository, that the svn client could check out from)?
I'd like to compare what I want to do with git. If I do a git init in a directory, I get the subfolder .git which contains exactly the same contents of a bare repo. I can clone this bare repo with git clone --bare ... and then upload it to a server - then I can directly clone using git clone http://... and the location of the bare repo (except that at first, git will complain with fatal: ... info/refs not found: did you run git update-server-info on the server?; this means that I should enable the default post-update hook [which] runs git update-server-info to keep the information used by dumb transports (e.g., HTTP) up-to-date.; or run git update-server-info in the bare repo, so info/refs is generated - only then can this bare repo on server be cloned on client via HTTP).
So, I'd consider the svnadmin created repo (with contents dav db format hooks locks README.txt) to be equivalent to the git bare repo (as they both contain the entire history, without the actual files), so I hoped that the svnadmin repo could be setup for read-only HTTP cloning in the same way (that is, just by copying that folder contents on the server). Unfortunately, that is not so - it seems that even with HTTP access, svn actually communicates with a form of WebDAV on the server (Subversion Users: Re: dav directory does not exist; SVN RedBook: What is WebDAV?). So I tried sabre/dav out, but after a succesful plain setup (tested with cadaver DAV command line tool), I can only get svn: OPTIONS of 'http://...': 200 OK (http://...) if I point to a svnadmin repo directory (or to its dav/ subdirectory).
I guess what I want is probably not possible at the time:
Re: SVN or git via WebDav using SabreDAV - Google Groups
The SVN protocol requires a TON of extensions to plain webdav to work. You're basically out of luck here.
... but I wanted to confirm for sure with this question...
Thanks to the answer from #Evert; but unfortunately svnsync doesn't seem to help me here (it fails with "Repository moved permanently"); here is a set of commands that I run in bash on an Apache server directory, with some command responses written prefixed with #:
svn --version
# svn, version 1.6.6 (r40053)
cd /media/www
svnadmin create mytest.svnfs
svn co file:///media/www/mytest.svnfs mytest.svn
cd mytest.svn
echo aaa >> test.txt
svn add test.txt
svn commit -m "init commit"
echo bbb >> test.txt
svn add test.txt
svn commit -m "2nd com mit"
wget -q --no-check-certificate http://localhost/mytest.svn -O - | head --bytes 120
# <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
# <html>
# <head>
# <title>Index of /mytest.svn</title>
cd ..
svnadmin create mytest.mirror
cat > mytest.mirror/hooks/pre-revprop-change <<'EOF'
#!/bin/sh
USER="$3"
if [ "$USER" = "syncuser" ]; then exit 0; fi
echo "Only the syncuser user can change revprops" >&2
exit 1
EOF
chmod +x mytest.mirror/hooks/pre-revprop-change
cat > mytest.mirror/hooks/start-commit <<'EOF'
#!/bin/sh
USER="$2"
if [ "$USER" = "syncuser" ]; then exit 0; fi
echo "Only the syncuser user may commit new revisions" >&2
exit 1
EOF
chmod +x mytest.mirror/hooks/start-commit
ls --ignore="*.tmpl" mytest.mirror/hooks/
# pre-revprop-change start-commit
svnsync initialize file:///media/www/mytest.mirror http://localhost/mytest.svnfs/ --sync-username syncuser --sync-password syncpass
# svnsync: Repository moved permanently to 'http://localhost/mytest.svnfs/'; please relocate
# trying the working copy (even if it shouldn't work):
svnsync initialize file:///media/www/mytest.mirror http://localhost/mytest.svn/ --sync-username syncuser --sync-password syncpass
# svnsync: Repository moved permanently to 'http://localhost/mytest.svn/'; please relocate
I wrote that answer, and it still holds true.
In a nutshell:
The SVN server can speak webdav, Delta-V (a versioning extension for webdav)
The SVN client takes advantage of that server, but also requires svn extensions.
This was true several years ago, so the situation may have changed... but I sincerely doubt it.
However.. for what you want to do, it sounds like you just want to use svnsync.
http://svnbook.red-bean.com/en/1.7/svn.reposadmin.maint.html#svn.reposadmin.maint.tk.svnsync

Running Symfony App Console From any Folder

When I install a new Symfony application, either via composer or by downloading it directly, it ships with a command line console application. I can run this application with the following command
$ php app/console help
In other systems that have developer command line applications, (Drupal's drush, Magento's n98-magerun, etc.), the application is capable of figuring out where the root folder is when you're deep in the file hierarchy, and you can run the application from anywhere
$ cd some/drupal/path
$ drush //still works!
To do something similar with Symfony's app/console, you need to construct this path yourself
$ cd some/symfony/path
$ php ../../../app/console
And even this may not work if the command relies on the PHP working directory being the root directory.
Is there a standard/well-supported way to get the "run from any folder" behavior of other CLI applications with Symfony's app/console?
I use following console script for this purpose:
#!/usr/bin/env php
<?php
function fileLocator($file =null, $maxDepth = 10, $currentDir = ".")
{
if(empty($file)){
return false;
}elseif(file_exists($currentDir . "/$file")){
return $currentDir;
}elseif(--$maxDepth){
return fileLocator($file, $maxDepth, $currentDir . "/..");
}else{
return false;
}
}
$projectDir = fileLocator('app', 10, getcwd());
if($projectDir){
$projectDir = realpath($projectDir);
if(substr($projectDir, -1) != DIRECTORY_SEPARATOR){
$projectDir .= DIRECTORY_SEPARATOR ;
}
$appDir = $projectDir . 'app';
}else {
die('You are not in symfony project');
}
// if you don't want to setup permissions the proper way, just uncomment the following PHP line
// read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
//umask(0000);
set_time_limit(0);
require_once $appDir.'/bootstrap.php.cache';
require_once $appDir.'/AppKernel.php';
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Debug\Debug;
$input = new ArgvInput();
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
if ($debug) {
Debug::enable();
}
$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->run($input);
For *nix users
Create console file with this code. put it in your global path of your choice(like /usr/local/bin/)
give it executable permission
sudo chmod +x /usr/local/bin/console
you are ready to go. You can run console from within any directory of a symfony2 project.
For windows users:
Assuming you have your php path in path variable so you was able to execute console like php app/console.
create a console.php file with the same code. create a console.bat file with the following script:
#ECHO OFF
php "%~dp0sf.php" %*
copy both console.php and console.bat file in your php directory. Now you are ready to go.
Enjoy!!
you need to create a symlink
sudo ln -s /full/path/to/app/console /usr/local/bin/console
sudo chmod +x /usr/local/bin/console
then you can run sudo console help
Here's a solution implemented as a Bash script, so suitable under Linux/Mac or Cygwin's bash prompt under Windows. It should work fine even if you swap regularly between projects, as it doesn't rely on environment variables.
Make a script with the following contents, make it executable (using chmod a+x) and then put it in your path:
#!/bin/sh
while [[ "`pwd`" != "/" ]]; do
app_dir=`find \`pwd\`/ -maxdepth 1 -name 'app'`
if [ -f "$app_dir/console" ]; then
php $app_dir/console $#
break
fi
cd ..
done
Then just use it anywhere within your Symfony project, and use it like you would use "php app/console". It doesn't depend on any environment variables - all it does is recursively look at parent folders from where you're located, looking for app/console, and then runs it with any and all the parameters you pass to it (that's what the $# symbol is for).
I created a Bundle for this to resolve. It is currently only a bash/fish script, which creates something like a virtual environment:
$ composer require sk/symfony-venv
// [...] wait for install
$ . vendor/bin/activate
(project) $ console
On https://github.com/skroczek/symfony-venv you can read more. Feedback is welcome. :)

Cloning git in bash script called from php webpage

I have very annoying problem here that I am completely lost on.
Am just trying to run a bash script from a php page.
The bash script is a long one.... so I created a caller.sh which calls the ./mainScript.sh to run in the background in the following:
nohup /bin/bash /home/test/customcoincode/CoinCreationBashFile.sh $coinName $coinNameAbreviation $blockReward $blockSpacing $targetTimespan $totalCoins $seedNode $nameSeedNode $headline >> /tmp/BASH2log.txt 2>&1 &
in reading my log file it seems some variables are not being passed in...
and at the following lines of code:
echo "Creating New Coin - Downloading code base repo"
echo "$localFolder/$coinName"
mkdir -p "$localFolder/$coinName";
cd "$localFolder/$coinName"
git clone "$baseRepository" "$localFolder/$coinName"
echo "Made it here 1"
i get outputs of:
Creating New Coin - Downloading code base repo
/home/test/Foocoin
cloning into '/home/test/Foocoin'
could not create directory '/var/www/.ssh'
host key verification failed
blah blah ....
Why is it looking in the /var/www/ directory?? works fine if I run the script from terminal?
many thanks
So to pack up my comments in an answer:
The shell script is now run as apache, as git uses ssh, corresponding config files are needed. Which were created in /var/www; apaches home directory. Apache did not have write permissions in /var/www thus could not create these files.
To resolve, create the /var/www/.ssh directory yourself and give www-data (or whatever user apache runs under in your system) write access to that folder.
Next, github requires you to authorize ssh keys. It is safer to create a new one for apache in the newly created /var/www/.ssh directory and add this key to your github keychain.

Categories