PHP command line: enter data into executed function

Hello all

I’m writing a script to automatically push code to a git server.
I’m using php and running the script via the command line.
After asking the user to enter the branch and commit message, the following code runs:
exec(‘git config user.name "’ . $userName . ‘"’);
exec(‘git config user.email "’ . $userEmail . ‘"’);

exec('git checkout -b ’ . $branch);
exec(‘git add --all’);
exec(‘git commit -m "’ . $message . ‘"’);

exec('git push origin ’ . $branch);

When running the last command, the script stops and asks for a user name, then a password.
How can I enter that username and password via the script?
I don’t want to have to type in the user name and password each time.
I’ve been looking on the net for the past 2 days, and I can’t get this right.

Thanks in advance.
Have a lovely day.

You’re going to have a hard time with this. What are you trying to accomplish though? Just to run all of the commands in 1 go so you don’t have to do so much work? If so, why not just copy all of the commands from wherever you are pushing to and just run them all at once?

If you’re trying to run this through cron jobs, that’s a different story.

also you shouldnt need to git config every time?

Thanks guys.
Don’t worry about the git part.
Git just came about because it’s a nice example.
The crux of what I’m trying to do is execute a sub script from a parent script, and be able to read output from that script and write input into that script.
With corona lockdowns, I got time on my hands to learn new stuff.

If you generate an SSH key pair, add the private key to your key agent, then upload the public key to GitHub, you should be able to avoid entering your password when pushing to GitHub.

See here: https://help.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent

Other than that, if you are trying to build a CLI to interact with the GitHub API in any way, you’ll need to implement one of their authentication strategies. For example by generating an OAUth token, which you’ll store and send along with subsequent requests. I’ve no idea what this would look like in PHP, but in Node, you can (still) use a library such as @octokit/auth-basic. I say still, as this strategy has been deprecated by GitHub, who want to move people to their web application flow.

You actually need multiple things. I created a project that backs up a game server I have to another disk. Then it also pushes that backup to a Github repo as a fail safe. When I was trying to write it, I had a lot of headaches until I found a source that had 1 file that was able to achieve what I wanted to.

Anyways, for my project, I needed an OAuth token for running cURL to create a private dynamic repo on Github. Then I needed an actual password and username (which they don’t recommend anymore since they want people to switch to the OAuth API) to authenticate to access that private repo. Then I ran that 3rd party file to push my files to Github.

Though I was running all of this under cron jobs so my example might be too extreme for what the OP is trying to do.

That doesn’t seem right. You should be able to pass the access token along with the request to avoid entering your username and p/w.

Yeah, I don’t know. They have a really strange way of doing it. I think they want people to use OAuth to authenticate first, then be able to send in a request using an access token. Problem with this is, it’s great on the web, but not CLI. I’m not sure if it asks for username and password if you’re not logged in via CLI, but if it does, it’s not very intuitive. That would defeat the whole purpose of requiring the OAuth to authenticate (meaning you still are required to input a username and password).

When I wrote my backup program, I was using a personal access token which should bypass the need to authenticate because this personal access token says “Hey, I am who I say I am”. But without the 1 line that uses a username and password, it’ll actually return this message.

stdClass Object
(
    [message] => Requires authentication
    [documentation_url] => https://developer.github.com/v3/repos/#create
)

Which means you still are required to authenticate using a username and password which defeats the purpose of trying to avoid it altogether. Maybe someone with a better approach could point the way for the OP.

I would still stand by what I said. It seems the OP is trying to execute git commands from within a PHP script (as opposed to interacting with the GH API), so I would see what happens using the SSH method. If that doesn’t work, I would look for a PHP library that implements one of GH’s auth strategies.

A quick search turns up:

Opauth being a multi-provider authentication framework for PHP

3 Likes

+1 for the SSH auth method. The username / password method is there for interactive use, not through a script.

Hi all

Thanks for the replies.
However, you are all missing the point.
I am trying to figure out how to send input to a command that I can run in PHP.
The git example, is just an example.
The title of the post is about how to enter data into an executed function, not about getting git working.

I’ve since found and tried proc_open(), but I still can’t get it to actually send the input to the git push command.

Thanks.

Would be nice next time to tell that up front :slight_smile:

Anyway, can you show us the code you came up with for proc_open()? Because that should work when done correctly [for most programs].

1 Like

So in this example you want git to ask PHP to ask the user for input, then you want PHP to give that input back to git? I’m not sure that’s possible. A script that’s being run by another script isn’t being run in the terminal and can’t interact with the user.

In this instance, you could use PHP’s readline() function to get the user’s input, then run git push with a host parameter including the username and password:

git push https://$username:$password@mygithost.com/repository.git

How you’d do it with your particular script will be different though.

I can get proc_open to work in another script.
Here is what I’ve tried for this script.

$branch = 'branch1';

$desc = array(
  0 => array("pipe" , "r"),
  1 => array("pipe" , "w")
);

$pipes = [];
$process = proc_open('git push origin ' . $branch , $desc , $pipes);

That’s the basic proc_open().

Where the script gets stuck, is where it asks for the user name.
At that point, I write the user name with fwrite(), but it just sticks around there.
I also fwrite(PHP_EOL) to simulate enter, but it won’t go past that point.

I tried stream_set_blocking() to stop the out, so I can just write the username, but no luck.
I tired fflush(), but no luck (I found another example that did this, so I gave it a bash.)
I tried a whole lot of other stuff, but I can’t get it to go past the point of asking for the user name.

Yeh, I don’t think you’ll get further. The command git push is trying to be interactive, but you’re not running it in a terminal so it has nothing to interact with. You need to find a way to run your script without interaction.

Why do you think that is?
I’ve seen proc_open interact with other external commands, and I made a small script, that runs a small sub script that I made, and it works no problem (the sub script asks for a user name, then waits for the user to enter it. The parent script, reads the output until the script asks for an input, then enters the user name, then reads the output again).
Why do you think another command (git push), can’t work in the same way?

That’s new to me then, I must be wrong. If you’ve had another script work this way, does git push not work with the same approach?

Yes. That’s what’s so frustrating.
As far as I can tell from reading about proc_open(), the purpose of it, is to be able to read and write to streams that are run in a child process.
So why does it work for some, and not others…?
Rather frustrating.

This rather old question on SO suggests that redirection of stdin / out / err doesn’t work on git “because it runs git-remote-http underneath which prompts for password on TTY.”

3 Likes

Thank you.
This was very enlightening.
I appreciate your input.