单引号变量包含一个变量

时间:2020-03-06 15:14:51

标签: shell variables unix

我正在使用sqlplus从包含shell命令的列中获取数据。

    services.AddHttpClient<ITCMCMClientService, TCMCMClientService>
        (client => { client.BaseAddress = new Uri(Configuration.GetValue<string>("ApexOneBackEnd")); })
            .ConfigurePrimaryHttpMessageHandler<MyHttpClientHandler>();

exec_cmd包含一个shell变量作为参数

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.Security.Cryptography.CryptographicException: m_safeCertContext is an invalid handle.
   at System.Security.Cryptography.X509Certificates.X509Certificate.ThrowIfInvalid()
   at System.Security.Cryptography.X509Certificates.X509Certificate2.get_HasPrivateKey()
   at System.Net.Security.CertificateHelper.GetEligibleClientCertificate(X509Certificate2Collection candidateCerts)
   at System.Net.Security.CertificateHelper.GetEligibleClientCertificate(X509CertificateCollection candidateCerts)
   at System.Net.Http.HttpClientHandler.<set_ClientCertificateOptions>b__70_0(Object sender, String targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, String[] acceptableIssuers)
   at System.Net.Security.SslStream.UserCertSelectionCallbackWrapper(String targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, String[] acceptableIssuers)
   at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint)
   at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset, Int32 count, Byte[]& output)
   at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offset, Int32 count)
   at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslStream.ProcessAuthentication(LazyAsyncResult lazyResult, CancellationToken cancellationToken)
   at System.Net.Security.SslStream.BeginAuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback asyncCallback, Object asyncState)
   at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__65_0(SslClientAuthenticationOptions arg1, CancellationToken arg2, AsyncCallback callback, Object state)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl[TArg1,TArg2](Func`5 beginMethod, Func`2 endFunction, Action`1 endAction, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions)
   at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2](Func`5 beginMethod, Action`1 endMethod, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions)
   at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2](Func`5 beginMethod, Action`1 endMethod, TArg1 arg1, TArg2 arg2, Object state)
   at System.Net.Security.SslStream.AuthenticateAsClientAsync(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at ApexOne.SPA.Data.Services.TCMCMClientService.GetPostesAsync(String envName) in E:\Source\Repos\ApexOne\ApexOne.SPA\Data\Services\TCMCMClientService.cs:line 37

script.sh:

cmd=`sqlplus -s username/password <<EOF
        set heading off
        set trimspool on
        set termout on
        set underline off
        set linesize 2000
        set pagesize 0
        SELECT exec_cmd
          FROM cmd_table
        exit;
        EOF`

此操作失败,因为$ echo $cmd script.sh $UP 包含文字字符串#!/bin/sh connection=$1 echo "exit" | `sqlplus -s -l $connection` 而不是$connection的值。

1 个答案:

答案 0 :(得分:0)

使用eval作为命令求值字符串:

eval "$cmd"

请小心,因为这将在当前进程中运行命令。它可能会更改变量或对脚本执行其他意外操作。显式调用一个子shell会更安全,该子shell将在一个隔离的子进程中运行该命令:

sh -c "$cmd"

要使后者起作用,请确保导出UP

UP='...'
export UP

sh -c "$cmd"

也请摆脱sqlplusscript.sh周围的反引号。

echo "exit" | sqlplus -s -l $connection